I have a question: What do you expect for the following common
INTEGER(c_int) :: I
COMMON /a/ i
Is it interoperable with C's
struct {
int i;
} a;
or with
int a;
If the common block contains several items, the answer "struct" makes
sense, but for a single variable, it is a bit unclear. In many cases,
using a struct or a single variable does not make a difference, but
sometimes it does!
* * *
The answer becomes easier if one uses "bind(c) :: /a/" because in this
case the Fortran 2003 standard gives an answer:
"A C variable with external linkage interoperates with a common block
that has been specified in a BIND statement
(1) if the C variable is of a struct type and the variables that are
members of the common block are interoperable with corresponding
components of the struct type, or
(2) if the common block contains a single variable, and the variable is
interoperable with the C variable."
Tobias
PS: This is GCC bug 41227; currently gfortran has the bug that it always
uses a "struct" - also with BIND(C). This causes to my knowledge only a
problem with link-time optimization (-flto) which has been added in GCC
4.5 - but there "struct"-or-not does really matter.
C guarantees that a pointer to a struct, appropriately cast,
is equivalent to a pointer to the first member.
Is that enough to be sure?
(That int a; should be either outside any function or extern int a;)
Also, C guarantees that external variables are initialized, but
Fortran does not. That would seem to require that such variables
not be initialized in Fortran.
-- glen
Sorry, I do see a difference between having
int a and struct { int i; } a
and having for a struct "a"
int *p = (int*) &a;
Especially, both GCC and ifort reject the following code which should be
valid if it wouldn't matter:
struct { int i; } a;
int main() {
extern int a;
return 0;
}
But both show an error:
hjff.c(4): error: declaration is incompatible with previous "a"
(declared at line 1)
hjff.c:4:14: error: conflicting types for 'a'
Hiding the fact that you have different types by using different files
will bite back as soon as you have link-time optimization.
Thus, I still assume that you can have either a struct or have no
struct, i.e. that it matters. But if you can find something in the C99
standard which says otherwise, I am happy to be corrected:
http://www.open-std.org/JTC1/SC22/WG14/www/standards
(http://www.open-std.org/JTC1/SC22/WG14/www/docs/n1124.pdf)
* * *
Otherwise, as seemingly no one know what (s)he wants, any choice will
do. Thus I plan to do for non-BIND(C) COMMON blocks the same as for
BIND(C), even if it breaks a single-variable struct in someone's program
(at least when (s)he uses LTO).
Tobias