- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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?
1 Solution
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
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:
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]
Link Copied
2 Replies
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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:
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:
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]
![](/skins/images/7FC17B7B85029576C25F1E43CE255B51/responsive_peak/images/icon_anonymous_message.png)
Reply
Topic Options
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page