Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
28441 Discussions

warning #6375: Because of COMMON, the alignment of object is inconsistent with its type

rocket_man
Beginner
1,531 Views

I found a similiar post to this on this forum, but it didn't help, so I thought I would provide an example of my issue

REAL*8 A
REAL*8 B
REAL*8 C
REAL*8 D
REAL*8 E
REAL*8 F
REAL G
REAL H
REAL I
REAL J(3)
REAL K
REAL L
REAL M
REAL N
REAL O
REAL P
REAL Q
REAL R
REAL S
REAL*8 T
REAL*8 U
REAL V
REAL W

COMMON

/DSTRCT/A, B, C, D, E, F, G,
H, I, J, K, L, M,
N, O, P, Q, R,S,
T, U, V, W

I get this Warning#6375 on variable T and U

The fortran subroutine is compiled as a Lib and called by a C program that passes the same structure. Variables A-S pass as they should between the C and Fortran however the T U V and W just keep the value 0.0.

Any suggestions?

*
0 Kudos
1 Solution
Steven_L_Intel1
Employee
1,531 Views
There are a couple of different issues here. First, Fortran will warn when you use COMMON or EQUIVALENCE that forces a variable to be not naturally aligned, as this can hurt performance. There is an extensive discussion of this in the on-disk documentation under Optimizing Applications > Programming Guidelines > Setting Data Type and Alignment.

If you are sharing a data structure with C, you need to be aware of how C will pad (or not) the structure. The Fortran 2003 standard provides the abilty to declare an "interoperable" derived type variable which will align (or not) the components the same way that the "companion C processor" would. For example, you could use the following as an alternative to the COMMON declaration you have:

[fortran]module shared_data
use ISO_C_BINDING
type, bind(C) :: DSTRCT_TYPE
real(C_DOUBLE) :: A,B,C,D,E,F
real(C_FLOAT) :: G,H,I
real(C_FLOAT), dimension(3) :: J
real(C_FLOAT) :: K,L,M,N,O,P,Q,R,S
real(C_DOUBLE) :: T,U
real(C_FLOAT) :: V,W
end type DSTRCT_TYPE
type(DSTRCT_TYPE), bind(C,NAME="DSTRCT") :: DSTRCT
end module shared_data[/fortran]
This will create a variable DSTRCT which is interoperable with a C struct of the same name and layout. The compiler will automatically pad T and U as required to match what C does. Of course, if you use this technique, you have to refer to DSTRCT%T, etc., and not just T, but it is standard-conforming and guaranteed to be compatible with what C does. The NAME= in the declaration of DSTRCT is required to prevent downcasing of the name.

If you don't want to make this change, you can tell the compiler to pad the COMMON by bracketing the COMMON declaration with an OPTIONS directive, like this:

[fortran]!DEC$ OPTIONS /ALIGN=COMMONS=NATURAL
COMMON /DSTRCT/ ...
!DEC$ END OPTIONS[/fortran]

View solution in original post

0 Kudos
2 Replies
TimP
Honored Contributor III
1,531 Views
I suppose we may be beating a dead horse, if you don't want to take advantage of what you have read about this. If you want to use a C compiler which pads for alignment, you could follow the traditional rule of putting all the 64-bit data elements ahead of the 32-bit elements, or you could insert a dummy 32-bit element before the mis-aligned 64-bit data so as to pad it out explicitly, avoiding the situation where one compiler inserts padding and the other doesn't.
0 Kudos
Steven_L_Intel1
Employee
1,532 Views
There are a couple of different issues here. First, Fortran will warn when you use COMMON or EQUIVALENCE that forces a variable to be not naturally aligned, as this can hurt performance. There is an extensive discussion of this in the on-disk documentation under Optimizing Applications > Programming Guidelines > Setting Data Type and Alignment.

If you are sharing a data structure with C, you need to be aware of how C will pad (or not) the structure. The Fortran 2003 standard provides the abilty to declare an "interoperable" derived type variable which will align (or not) the components the same way that the "companion C processor" would. For example, you could use the following as an alternative to the COMMON declaration you have:

[fortran]module shared_data
use ISO_C_BINDING
type, bind(C) :: DSTRCT_TYPE
real(C_DOUBLE) :: A,B,C,D,E,F
real(C_FLOAT) :: G,H,I
real(C_FLOAT), dimension(3) :: J
real(C_FLOAT) :: K,L,M,N,O,P,Q,R,S
real(C_DOUBLE) :: T,U
real(C_FLOAT) :: V,W
end type DSTRCT_TYPE
type(DSTRCT_TYPE), bind(C,NAME="DSTRCT") :: DSTRCT
end module shared_data[/fortran]
This will create a variable DSTRCT which is interoperable with a C struct of the same name and layout. The compiler will automatically pad T and U as required to match what C does. Of course, if you use this technique, you have to refer to DSTRCT%T, etc., and not just T, but it is standard-conforming and guaranteed to be compatible with what C does. The NAME= in the declaration of DSTRCT is required to prevent downcasing of the name.

If you don't want to make this change, you can tell the compiler to pad the COMMON by bracketing the COMMON declaration with an OPTIONS directive, like this:

[fortran]!DEC$ OPTIONS /ALIGN=COMMONS=NATURAL
COMMON /DSTRCT/ ...
!DEC$ END OPTIONS[/fortran]
0 Kudos
Reply