Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Trying to make a borderline case in PR46982

5 views
Skip to first unread message

James Van Buskirk

unread,
Dec 16, 2010, 9:23:53 PM12/16/10
to
Consider PR46982:

C:\gfortran\clf\PR46982>type PR46982a.f90
module something_mod
integer, parameter :: dp = selected_real_kind(12)
type something_type
real(dp) :: a = 0.0_dp
real(dp) :: b = 0.0_dp
real(dp) :: c = 0.0_dp
end type something_type
type(something_type),save :: something
end module something_mod

use something_mod
integer :: something_array(size(transfer(something,(/0/))))
end

C:\gfortran\clf\PR46982>gfortran PR46982a.f90 -oPR46982a
PR46982a.f90:12.61:

integer :: something_array(size(transfer(something,(/0/))))
1
Error: The module or main program array 'something_array' at (1) must have
const
ant shape

This error sttement is correct because in N1830.pdf, section
5.3.16, it says:

"A variable, common block, or procedure pointer declared in the
scoping unit of a main program, module, or submodule implicitly has
the SAVE attribute, which may be con rmed by explicit specification."

But section 5.2.2 syas:

"An automatic data object is a nondummy data object with a type
parameter or array bound that depends on the value of a
specification-expr that is not a constant expression.

C513 An automatic object shall not have the SAVE attribute."

So it is required that

size(transfer(something,(/0/)))

be a constant expression (in f03, initialization expression).
It almost is; see section 7.1.12:

"(4) a specification inquiry where each designator or function
argument is
(a) a constant expression or
(b) a variable whose properties inquired about are not
(i) assumed,
(ii) deferred, or
(iii) defined by an expression that is not a constant
expression"

The specification inquiry is the SIZE intrinsic, but

transfer(something,(/0/))

is not a constant expression, nor is it a variable, so it flunks the
test and gfortran prints out an error message accordingly. We can
make it conform by making something a named constant or by moving the
automatic data object to a function or subroutine:

C:\gfortran\clf\PR46982>type PR46982b.f90
module something_mod
integer, parameter :: dp = selected_real_kind(12)
type something_type
real(dp) :: a = 0.0_dp
real(dp) :: b = 0.0_dp
real(dp) :: c = 0.0_dp
end type something_type
type(something_type),save :: something
end module something_mod

call sub;end;subroutine sub
use something_mod
integer :: something_array(size(transfer(something,(/0/))))
end

C:\gfortran\clf\PR46982>gfortran PR46982b.f90 -oPR46982b

C:\gfortran\clf\PR46982>PR46982b

C:\gfortran\clf\PR46982>type PR46982c.f90
module something_mod
integer, parameter :: dp = selected_real_kind(12)
type something_type
real(dp) :: a = 0.0_dp
real(dp) :: b = 0.0_dp
real(dp) :: c = 0.0_dp
end type something_type
type(something_type),parameter :: something = &
something_type(0,0,0)
end module something_mod

use something_mod
integer :: something_array(size(transfer(something,(/0/))))
end

C:\gfortran\clf\PR46982>gfortran PR46982c.f90 -oPR46982c

C:\gfortran\clf\PR46982>PR46982c

But to try to compose a borderline case the best I can come up with
is:

C:\gfortran\clf\PR46982>type PR46982d.f90
module something_mod
integer, parameter :: dp = selected_real_kind(12)
type something_type
real(dp) :: a = 0.0_dp
real(dp) :: b = 0.0_dp
real(dp) :: c = 0.0_dp
end type something_type
type(something_type),save :: something
end module something_mod

module gen
implicit none
interface sub
module procedure sub1,sub2,sub3,sub4,sub5,sub6,sub7
end interface sub
contains
subroutine sub1(x)
integer x(:)
write(*,'(a)') 'Subroutine sub1 was called.'
end subroutine sub1
subroutine sub2(x)
integer x(:,:)
write(*,'(a)') 'Subroutine sub2 was called.'
end subroutine sub2
subroutine sub3(x)
integer x(:,:,:)
write(*,'(a)') 'Subroutine sub3 was called.'
end subroutine sub3
subroutine sub4(x)
integer x(:,:,:,:)
write(*,'(a)') 'Subroutine sub4 was called.'
end subroutine sub4
subroutine sub5(x)
integer x(:,:,:,:,:)
write(*,'(a)') 'Subroutine sub5 was called.'
end subroutine sub5
subroutine sub6(x)
integer x(:,:,:,:,:,:)
write(*,'(a)') 'Subroutine sub6 was called.'
end subroutine sub6
subroutine sub7(x)
integer x(:,:,:,:,:,:,:)
write(*,'(a)') 'Subroutine sub7 was called.'
end subroutine sub7
end module gen

use something_mod
something%a = transfer([2,2],0.0_dp)
something%b = transfer([3,2],0.0_dp)
something%c = transfer([2,3],0.0_dp)
call sub(reshape([1],transfer(something,[0]),pad=[2]))
end

C:\gfortran\clf\PR46982>gfortran PR46982d.f90 -oPR46982d
PR46982d.f90:51.23:

call sub(reshape([1],transfer(something,[0]),pad=[2]))
1
Error: 'shape' argument of 'reshape' intrinsic at (1) must be an array of
consta
nt size

But this isn't really borderline either, although the error message
is possibly misleading. From section 13.7.140:

"SHAPE shall be a rank-one integer array. SIZE (x), where x is the
actual argument corresponding to SHAPE, shall be a constant
expression whose value is positive and less than 16. It shall
not have an element whose value is negative."

This, to my mind, is a stronger requirement on the SHAPE argument
than the error message tells us and definitely excludes this example.
So the only thing I could come up with was an error message that
might perhaps have been more closely worded.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end


0 new messages