1

In relation to a recent post regarding how to declare the array shape concisely, I tried the following three patterns, i.e., (A) automatic re-allocation, (B) sourced allocation, and (C) allocation with assumed shape. Then gfortran seems to give incorrect results for b(:,:) in the case of sourced allocation. Here, am I doing something wrong, or is this simply because it is not yet fully supported by gfortran? Although the latter seems likely, I am not very sure if my installation or usage of gcc5 and 6 is correct (I am using Linux x86_64).

program main
    implicit none
    integer, parameter :: p=3, q=4, r=5
    integer a( p, q, r ), i, j, k
    integer, allocatable :: b( :, : )

    a = reshape( [ ((( 100*i + 10*j + k, i=1,p), j=1,q), k=1,r) ], [p,q,r] )

    print *
    print *, "shape( a ) = ", shape( a )
    print *, "a(:,:,:) = ", a
    print *, "a(:,1,:) = ", a(:,1,:)

    b = a( :, 1, : )                           !! (A) automatic (re)allocation
    ! allocate( b, source = a( :, 1, : ) )     !! (B) sourced allocation
    ! allocate( b, mold = a( :, 1, : ) )       !! (C) allocation with assumed shape

    print *
    print *, "shape( b ) = ", shape( b )
    print *, "b(:,:) = ", b
end

Results: (In all cases, automatic reallocation gives the correct result.)

gfortran4.8.2
[A]
shape( b ) =   3   5
b(:,:) =  111  211  311  112  212  312  113  213  313  114  214  314  115  215  315
[B], [C]
f951: internal compiler error: Segmentation fault

gfortran5.2.1
[A]
shape( b ) =   3   5
b(:,:) =  111  211  311  112  212  312  113  213  313  114  214  314  115  215  315 
[B], [C]
allocate( b, source = a( :, 1, : ) )
         1
Error: Array specification required in ALLOCATE statement at (1)

gfortran6.0.0 (experimental)
[A]
shape( b ) =   3   5
b(:,:) =  111  211  311  112  212  312  113  213  313  114  214  314  115  215  315
[B]  <--- seems incorrect
shape( b ) =   3   5
b(:,:) =  0  -1094645928  57  141  241  341  142  242  342  143  243  343  144  244 344
[C]
shape( b ) =   3   5
b(:,:) = (garbage data, reasonable)

Intel Fortran 14.0.1 (-assume realloc_lhs)
[A]
shape( b ) =   3   5
b(:,:) =  111  211  311  112  212  312  113  213  313  114  214  314  115  215  315
[B]
shape( b ) =   3   5
b(:,:) =  111  211  311  112  212  312  113  213  313  114  214  314  115  215  315
[C]
shape( b ) =   3   5
b(:,:) =  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

Oracle Fortran 12.4
[A]
shape( b ) =  3 5
b(:,:) =  111 211 311 112 212 312 113 213 313 114 214 314 115 215 315
[B]
shape( b ) =  3 5
b(:,:) =  111 211 311 112 212 312 113 213 313 114 214 314 115 215 315
[C]
shape( b ) =  3 5
b(:,:) = (garbage data, reasonable)
Community
  • 1
  • 1
roygvib
  • 7,218
  • 2
  • 19
  • 36
  • I don't have the versions of gfortran to check, but there is perhaps something for you to try. In a [previous answer](http://stackoverflow.com/a/26952438) I noted that gfortran requires the array specification for `b` giving, regardless of the source expression. This is your 5.2.1 error. Could you try giving bounds (like `allocate(b(p,r), source=...)`) with 6 and see if the problem persists? – francescalus Dec 20 '15 at 18:25
  • @francescalus I have tried your suggestion, and even gfortra4.8 worked as expected with b(p,r) @@; (Though gcc6 still gave incorrect results, this is no surprise because it is a development version.) Actually, is it not standard conformant to write simply as "b" in the allocate statement (without p, r)? – roygvib Dec 20 '15 at 19:02

1 Answers1

2

Sourced allocation was introduced in Fortran 2003 and the rules/constraints were changed in Fortran 2008. Rejection of the program by gfortran 5.2.1 would appear to be a consequence of following F2003.

Under F2003 sourced allocation required the explicit specification of array bounds for the array to be allocated. Under F2008 this is not required, and additionally multiple objects to be allocated could be specified. So, your code isn't valid F2003.

The program (well, that allocation part) is, though, valid F2008: the bounds of the array to be allocated may come from the source expression just as the value does. The contiguity or otherwise of the array section shouldn't be important as it's the value (and bounds) of the expression being key. Naturally, the calculation of bounds of the expression array offers opportunity for things to go wrong.

In conclusion, the allocation statement is valid under F2008 but not under F2003. A compiler which is using the F2003 rules must be able to detect the violation rather than being free to give nonsense. But F2008 is easy enough to do buggily.

And, thanks to your testing, the safe way to write this code for gfortran would be

allocate(b(p,r), source=a(:,1,:))

Indeed, documentation for gfortran lists the giving of bounds as being "unimplemented".

francescalus
  • 30,576
  • 16
  • 61
  • 96
  • Initially, I didn't understand the meaning of the error message `Error: Array specification required in ALLOCATE statement at (1)` (of gfort5.2) but now it has become clear now :) Also, because gfort6.0 (expt.version) has been moving to full F2008, it now accepts the omission of (p,r) but still seems not giving the correct result. So it is probably safer to write (p,r) explicitly, for the time being. Thanks very much! – roygvib Dec 20 '15 at 19:45
  • Yes, F2008 doesn't have a "numbered constraint" on the bounds being given so the compiler doesn't need to complain if it's following that standard (under F2003 it cannot allow multiple sourced allocations). So the bug is not having the nicety of warning that the feature is unimplemented. – francescalus Dec 20 '15 at 19:53