Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

C interoperability question regarding COMMON

4 views
Skip to first unread message

Tobias Burnus

unread,
Jan 29, 2010, 12:38:23 PM1/29/10
to
Hello all,


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.

glen herrmannsfeldt

unread,
Jan 29, 2010, 2:16:10 PM1/29/10
to
Tobias Burnus <bur...@net-b.de> wrote:

> 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!

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

Tobias Burnus

unread,
Jan 30, 2010, 10:35:09 AM1/30/10
to
Am 29.01.2010 20:16, schrieb glen herrmannsfeldt:

> Tobias Burnus <bur...@net-b.de> wrote:
>> INTEGER(c_int) :: I
>> COMMON /a/ i
>
>> Is it interoperable with C's
>> struct { int i; } a;
>> or with
>> int a;
>
> 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?

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

0 new messages