This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: COMMON requires 4 bytes of padding at start


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]