This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: COMMON requires 4 bytes of padding at start
- From: Tobias Burnus <burnus at net-b dot de>
- To: Janus Weil <jaydub66 at googlemail dot com>
- Cc: Fortran List <fortran at gcc dot gnu dot org>
- Date: Thu, 11 Sep 2008 19:13:16 +0200
- Subject: Re: COMMON requires 4 bytes of padding at start
- References: <854832d40809110401j31ad385fna44602da769830f1@mail.gmail.com>
Hi Janus,
Janus Weil wrote:
> when compiling old F77 code with gfortran, i get lots of warnings of the type:
>
> Warning: COMMON 'foo' at (1) requires 4 bytes of padding at start
>
> A simple test case which triggers this is the following:
>
> implicit none
> integer(kind=4) :: n
> real(kind=8) :: p
> common /foo/ n,p
> end
>
> Now I have two questions:
>
> 1) Should I take this warning seriously (i.e. does it have any
> consequences) or can I simply ignore it?
>
That completely depends on how you use COMMON - if you use the same
variables everywhere, it works. But if you don't then you might be in
trouble.
Assume that you have an integer(4) n4 and a real(8) r8. Then you have
NNNNRRRR|RRRR
in memory which is "misaligned"; you rather want to have
____NNNN|RRRRRRRR
that is you want to have a padded first item. The reason is that for
good performance (loading variable from the memory into a register)
REAL(8) data should be aligned such that its base address is a multiple
of 8. For a variable outside common, the compiler can do so easily, but
in common that clashes with the Fortran standard. Assume the following
program and compile it in two separate files:
----------------------------------
subroutine one()
implicit none
integer :: n1,n2,n3,n4
common /foo/ n1,n2(2),n3,n4
print *, n3, n4
end subroutine one
----------------------------------
program prog
implicit none
integer :: n1,n2,n3
real(8) :: r1
common /foo/ n1,r1,n2,n3
n2 = 2
n3 = 3
call one()
end program prog
----------------------------------
(I'm not sure whether the program is valid ISO Fortran, but I'm quite
certain that one can find similar code.)
One expects that the program prints "2 3" but due to inserted padding,
it prints "0 2". Thus whether the warning is important or not, depends
on your program. If you have always the same variable types in COMMON
there should be no problem.
Notes:
a) I prefer IFORT: It by default uses misaligned memory (and thus prints
the expected "2 3") but offers the options -align commons (default:
nocommons) and -align nosequence (default: sequence); it prints the message:
warning #6375: Because of COMMON, the alignment of object is
inconsistent with its type [R1]
I think gfortran should do alike as one might otherwise get surprising
results. In case of ifort it is merely a performance warning.
b) g95 uses (like ifort) unaligned memory but prints no warning; NAG f95
like gfortran does padding and prints "Warning: Hardware-imposed
alignment of R1 is non-standard".
c) For the alignment issue, I think the ifort manual might be useful:
http://www.intel.com/software/products/compilers/flin/docs/main_for/mergedprojects/optaps_for/fortran/optaps_prg_algn_f.htm
d) Action items: I suggest
(i) To add an option to optionally do no padding [for COMMON] and enable
that option by default (I think we can ignore SEQUENCE)
(ii) Document that option such that the implications of the option is clear
Janus, could you open a PR?
Tobias