Is this a legal program?
Gfortran 4.4 appears to segfault.
Was working fine for ages.
Alexei
program p
real(8) :: empty(0, 3), square(0)
square = sum(empty * empty, 2)
print *, "square=", square
end
!
! Example session:
!
! $ gcc --version
! gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
! Copyright (C) 2009 Free Software Foundation, Inc.
! This is free software; see the source for copying conditions. There
is NO
! warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
! $ gfortran p.f90
! $ gdb ./a.out
! GNU gdb (GDB) 7.1-ubuntu
! Copyright (C) 2010 Free Software Foundation, Inc.
! License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/
gpl.html>
! This is free software: you are free to change and redistribute it.
! There is NO WARRANTY, to the extent permitted by law. Type "show
copying"
! and "show warranty" for details.
! This GDB was configured as "i486-linux-gnu".
! For bug reporting instructions, please see:
! <http://www.gnu.org/software/gdb/bugs/>...
! Reading symbols from /home/alexei/darcs/ttfs-mac-1/a.out...(no
debugging symbols found)...done.
! (gdb) run
! Starting program: /home/alexei/darcs/ttfs-mac-1/a.out
!
! Program received signal SIGSEGV, Segmentation fault.
! 0x001908e8 in _gfortran_sum_r8 () from /usr/lib/libgfortran.so.3
! (gdb) quit
> Is this a legal program?
> Gfortran 4.4 appears to segfault.
> Was working fine for ages.
>
> program p
> real(8) :: empty(0, 3), square(0)
>
> square = sum(empty * empty, 2)
>
> print *, "square=", square
>
> end
It is not a legal program for some compilers, as 8 is not necessarily a
valid kind number. In fact, the first compiler I tried it on rejected it
for that reason. I doubt that's what you were asking about, though.
Other than that, I see nothing wrong with the code. There is no
restriction in the standard that mentions zero size as being
prohibitted, and I see no inherent reason why it would need to be
prohibitted. To the contrary, the standard even says under case (i) that
the result "has the value zero if ARRAY has size zero." Now that case
doesn't directly apply because it is for the simple form sum(array), but
it does provide direct evidence that zero-sized arrays were not
overlooked and were even explicitly allowed.
For your case, the result has no elements, so the description of the
computation of the value of each element is moot. The description of the
result characteristics gives a result shape of [0], which matches the
way your code uses it.
--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
> ! $ gcc --version
> ! gcc (Ubuntu 4.4.3-4ubuntu5) 4.4.3
> ! Copyright (C) 2009 Free Software Foundation, Inc.
2009 -- that's pretty old in gfortran years. But it still seems to
crash at runtime with recent gfortran 4.6.
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
> real(8) :: empty(0, 3), square(0)
> square = sum(empty * empty, 2)
It looks legal for Fortran 2003. I didn't check earlier versions.
sum(zero length array) is defined to be zero, and sum(array,dim)
is defined in terms of sum(array) in a way that is hard to read,
but sounds right.
-- glen
I agree it is hard to read, but for the zero-sized case, you don't
actually have to read it. That's because the hard-to-read part is all
about specifying the values of the elements of the result. When the
result doesn't have any elements, you don't have to bother to read that
whole section about the result value. You can stop after reading the
section on the result characteristics (which is where it specifies what
the shape will be and you can see that the result is zero sized).
Well, it worked in GCC 4.1 and it doesn't in 4.3 to 4.6.
By the way, the breakage ("regression") is caused due to the zero-sized
LHS, the zero-sized RHS is properly dealt with. Consequently, it works
if one use "print *, sum(...)" or if the LHS is an allocatable
[(re)alloc on assignment].
Should be relatively straight forward to fix.
Somehow, zero-sized arrays and ENTRY are two features which tend to get
forgotten when implementing new features -- especially in rare
combinations like a character-returning BIND(C) ENTRY function. But
there are countless other possibilities for bugs.
Tobias
>
> > It looks legal for Fortran 2003. I didn't check earlier versions.
>
> > sum(zero length array) is defined to be zero, and sum(array,dim)
> > is defined in terms of sum(array) in a way that is hard to read,
> > but sounds right.
>
> I agree it is hard to read, but for the zero-sized case, you don't
> actually have to read it.
Thanks for confirmation, Tobias filed a bug report
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48066
For reference, the workaround in my case was
squares = vectors(:, 1)**2 + vectors(:, 2)**2 + vectors(:, 3)**2
Alexei
>> sum(zero length array) is defined to be zero, and sum(array,dim)
>> is defined in terms of sum(array) in a way that is hard to read,
>> but sounds right.
> I agree it is hard to read, but for the zero-sized case, you don't
> actually have to read it. That's because the hard-to-read part is all
> about specifying the values of the elements of the result. When the
> result doesn't have any elements, you don't have to bother to read that
> whole section about the result value. You can stop after reading the
> section on the result characteristics (which is where it specifies what
> the shape will be and you can see that the result is zero sized).
Well, you should read it enough to be sure that it says that zero
sized arrays, other than the dim dimension also work. Even that
is pretty hard to extract. But yes, the result value is even harder.
-- glen