Mis-alignment of 32-bit BIND(C) globals

Mis-alignment of 32-bit BIND(C) globals

I am using ISO_C_BINDING to access 32-bit global variables in C object code from Fortran. In the C object code, globals are aligned at 4-byte boundaries, but Fortran object code expects 8-byte boundaries.

Example code:

/* data.c */
int global1=1;

! globals.f90
module globals
use iso_c_binding
integer(C_int), bind(C,name="global1") :: global1
end module globals
use globals
write (*,*) 'global1=',global1

$ icc -c data.c
$ ifort -c global.f90
$ ifort -o global global.o data.o
ld: Warning: alignment 4 of symbol `global1' in data.o is smaller than 8 in global.o

With the 32-bit compilers, both align at 4-byte boundaries. With 64-bit, Fortran switches to 8-byte boundaries, while icc and gcc both remain at 4-byte. I have tried passing various alignement switches to ifort, but get the same results.

The resulting code seems to work, so perhaps the linker can handle the problem and produce correct code. It would be nice to know if this warning can in fact be safely ignored, and if there are any compiler switches or directives to get the correct result. It also seems likely to be a compiler bug.

My compiler version is 12.1.0, running on a Fedora 15

3 posts / 0 new
Last post
For more complete information about compiler optimizations, see our Optimization Notice.

Looking at how the link process works, I see that Fortran sets up 8-byte aligned common definitions for the globals, and those get overriden by the definitions in data.o, which can be seen by passing the "--warn-common" flag to the linker:

$ ifort -Wl,--warn-common -o global global.o data.o
data.o: warning: definition of `global1' overriding common
global.o: warning: common is here
ld: Warning: alignment 4 of symbol `global1' in data.o is smaller than 8 in global.o

I think the fact that the C globals are overriding the common objects means that the global.o symbols are unused and essentially ignored, so that the alignment difference should not cause any problems. The globals are 32-bit, so the smaller alignment size is also not a performance issue.

The hardware fixes up alignment of 64-bit data types at odd multiples of 4 bytes. Normally, you would not see the performance penalty when processing scalar data. gcc is supposed to assure 16-byte alignment of any object which uses 16 bytes or more, and 8-byte alignment of an 8-byte object. 4-byte alignment of a 32-bit object is perfectly fine. It's somewhat strange seeing a warning about this.
If you want higher alignment in gcc. you must use e.g. __attribute__ ((aligned(16))) in the variable definition. icc accepts that and the equivalent declspec.

Leave a Comment

Please sign in to add a comment. Not a member? Join today