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

BIND(C) functions in a module error

116 views
Skip to first unread message

M.S. Breitenfeld

unread,
Aug 6, 2010, 12:32:14 PM8/6/10
to
I'm having problems compiling the code below using gfortran
(4.2,4.3,4.4.4.5). It gives the error:

Error: Type 'link_info' at (1) is a parameter to the BIND(C) procedure
'liter_cb' but is not C interoperable because derived type 'info_t' is
not C interoperable

when I remove the module and compile just the function it compiles fine.
Can I not use a bind(C) function in a module?


MODULE liter_cb_mod
USE ISO_C_BINDING
CONTAINS
FUNCTION liter_cb(link_info) bind(C)
USE ISO_C_BINDING
IMPLICIT NONE

INTEGER(c_int) liter_cb

TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t

TYPE(info_t) :: link_info

liter_cb = 0

END FUNCTION liter_cb

END MODULE liter_cb_mod

PROGRAM main

END PROGRAM main

Richard Maine

unread,
Aug 6, 2010, 1:00:25 PM8/6/10
to
M.S. Breitenfeld <msbr...@gmail.com> wrote:

> I'm having problems compiling the code below using gfortran
> (4.2,4.3,4.4.4.5). It gives the error:
>
> Error: Type 'link_info' at (1) is a parameter to the BIND(C) procedure
> 'liter_cb' but is not C interoperable because derived type 'info_t' is
> not C interoperable

That error message is pretty clearly bogus, as your info_t is about as C
interoperable as a derived type can be.



> when I remove the module and compile just the function it compiles fine.
> Can I not use a bind(C) function in a module?

Yes, you can. Note that the above error message doesn't say anything
like that. What it does refer to isn't anything that would relate to
being in a module or not. Even if it were the case (it isn't) that you
can't do such a thing in a module, I'd say that it would constitute a
compiler bug to generate such a wildly irrelevant error message. Sounds
to me like a hint that something else is wrong.

The code looks fine to me as is. Both the compilers I have handy on this
machine (g95 and Nag) are happy with it.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain

steve

unread,
Aug 6, 2010, 1:32:02 PM8/6/10
to
On Aug 6, 10:00 am, nos...@see.signature (Richard Maine) wrote:

> M.S. Breitenfeld <msbrtn...@gmail.com> wrote:
> > I'm having problems compiling the code below using gfortran
> > (4.2,4.3,4.4.4.5). It gives the error:
>
> > Error: Type 'link_info' at (1) is a parameter to the BIND(C)  procedure
> > 'liter_cb' but is not C interoperable because derived type 'info_t' is
> > not C interoperable
>
> That error message is pretty clearly bogus, as your info_t is about as C
> interoperable as a derived type can be.
>
> > when I remove the module and compile just the function it compiles fine.
> > Can I not use a bind(C) function in a module?
>
> Yes, you can. Note that the above error message doesn't say anything
> like that. What it does refer to isn't anything that would relate to
> being in a module or not. Even if it were the case (it isn't) that you
> can't do such a thing in a module, I'd say that it would constitute a
> compiler bug to generate such a wildly irrelevant error message. Sounds
> to me like a hint that something else is wrong.
>
> The code looks fine to me as is. Both the compilers I have handy on this
> machine (g95 and Nag) are happy with it.

How does one USE the function from the module?

--
steve

M.S. Breitenfeld

unread,
Aug 6, 2010, 1:59:25 PM8/6/10
to
It's used as a callback function (it's called from C) but used in the
main program by C_FUNLOC(liter_cb)

I went ahead and submitted a gfortran bug report.

steve

unread,
Aug 6, 2010, 7:29:11 PM8/6/10
to
On Aug 6, 10:59 am, "M.S. Breitenfeld" <msbrtn...@gmail.com> wrote:
> It's used as a callback function (it's called from C) but used in the
> main program by C_FUNLOC(liter_cb)
>
> I went ahead and submitted a gfortran bug report.
>

Remove mangle context due to top posting.

That does not answer my question. AFAIU, the
routine cannot be USEd in any other fortran
procedure.

--
steve

Richard Maine

unread,
Aug 6, 2010, 8:23:41 PM8/6/10
to
steve <kar...@comcast.net> wrote:

> That does not answer my question. AFAIU, the
> routine cannot be USEd in any other fortran
> procedure.

False. This sounds like a fairly basic misunderstanding of bind(c).
Bind(c) does not mean that something cannot be invoked from Fortran. It
just means that the invocation method is compatible with C.

There are actually 2 completely different ways that a bind(c) module
procedure can be invoked from Fortran code.

The first way is via C interop. A bind(c) procedure is compatible with
invocation via C. We know how to invoke C compatible procedures. Put the
two together, and viola. This is independent of whether the procedure is
in a module or not. It is a little wordy in this case because of the way
that the type info_t is defined within the function. (I wouldn't do it
that way, but it is allowed). That means I end up having to repeat the
darned thing 3 times: 1) within the function itself, 2) within the
interface body that is needed where we invoke the function, and 3 within
the scope where we invoke the function because we'll need it to declare
the actual argument. Wordy, but valid. The following wordy code works
fine in g95 and prints 0 as expected. I have not touched a character of
the original module.

MODULE liter_cb_mod
USE ISO_C_BINDING
CONTAINS
FUNCTION liter_cb(link_info) bind(C)
USE ISO_C_BINDING
IMPLICIT NONE

INTEGER(c_int) liter_cb

TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t

TYPE(info_t) :: link_info

liter_cb = 0

END FUNCTION liter_cb

END MODULE liter_cb_mod

PROGRAM main
USE ISO_C_BINDING
interface


FUNCTION liter_cb(link_info) bind(C)
USE ISO_C_BINDING
IMPLICIT NONE
INTEGER(c_int) liter_cb
TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t
TYPE(info_t) :: link_info

END FUNCTION liter_cb
end interface

TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t

type(info_t) :: link_info

write (*,*) liter_cb(link_info)

END PROGRAM main

Nag has a problem, but I'll cover that below.

The second way to invoke a bind(c) procedure defined in a module is to
USE the module. The rules for USE do not have any exceptions for bind(c)
procedures. That means they are supposed to work. Yes, that means that,
among other things, USEing the module has to pass along the information
that the procedure in question is a bind(c) ones. But then USEing a
module is supposed to simillarly pass along darn near everything. The
following much shorter main program uses this method. I elided the
module here because it is also unchanged from the original and one copy
per post seemed enough

PROGRAM main
use liter_cb_mod


TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t

type(info_t) :: link_info

write (*,*) liter_cb(link_info)

END PROGRAM main

This also works fine and gives the expected result with g95. Again, Nag
fails on it.

The problem with the Nag compiler here isn't directly related to
invoking a bind(c) module procedure. It has more to do with the bind(c)
type used for the argument. In the version with the USE statement, Nag
(v 5.2 on my Mac) gives me the message

Incorrect data type INFO_T (expected INFO_T) for argument
LINK_INFO (no. 1) of LITER_CB

The message about finding INFO_T when it expected INFO_T looks confusing
on the surface, but I think I can interpret it, realizing that there are
2 separate declarations of types named INFO_T. I'm thinking that someone
at Nag forgot that bind(c) acts like sequence in that you can have 2
separate declarations that count as the same type.

I'll throw in yet another lament that J3 failed to understand my
suggestion that bind(c) types be referred to as a special sort (I
carefully avoid saying type, kind, class or a bunch of other words that
are basically synonymous in English, but have special meaning in
Fortran) ot sequence type. They really do act like sequence. Pretty much
everywhere the standard previously said "sequence", it had to be
modified to say "sequence or bind(c)". There were several errors made in
missing some such places in drafts of f2003. If we had just said that
bind(c) was a sort of sequence, the errors would not have happened.
Looks like compilers might be prone to exactly the same error. Think
I'll submit a bug report on this one to Nag (after checking to make sure
I have the most current patch release installed; I haven't checked that
yet).

Anyway, if I move the derived type definition out to module scope, where
I would normally put it if I were writing the code, then the whole thing
becomes

MODULE liter_cb_mod
USE ISO_C_BINDING


TYPE, bind(C) :: info_t
INTEGER(c_int) :: type
END TYPE info_t

CONTAINS
FUNCTION liter_cb(link_info) bind(C)
USE ISO_C_BINDING
IMPLICIT NONE

INTEGER(c_int) liter_cb


TYPE(info_t) :: link_info

liter_cb = 0

END FUNCTION liter_cb

END MODULE liter_cb_mod

PROGRAM main
use liter_cb_mod

type(info_t) :: link_info

write (*,*) liter_cb(link_info)

END PROGRAM main

which works fine with both Nag and g95 on this machine.

dpb

unread,
Aug 6, 2010, 9:36:55 PM8/6/10
to
Richard Maine wrote:
...

> There are actually 2 completely different ways that a bind(c) module
> procedure can be invoked from Fortran code.
>
> The first way is via C interop. A bind(c) procedure is compatible with
> invocation via C. We know how to invoke C compatible procedures. Put the

> two together, and viola. ... we have string music in an alto range. :)

<Yeah, I know, groan, but I simply couldn't help it, Richard! :) >

--

Richard Maine

unread,
Aug 6, 2010, 10:02:57 PM8/6/10
to
dpb <no...@non.net> wrote:

Voila! :-)

glen herrmannsfeldt

unread,
Aug 6, 2010, 11:59:50 PM8/6/10
to
Richard Maine <nos...@see.signature> wrote:
(snip)


> There are actually 2 completely different ways that a bind(c) module
> procedure can be invoked from Fortran code.

I presume that is in addition to calling a C function that
calls the bind(c) module procedure from a passed c_funloc()
pointer.

-- glen

Richard Maine

unread,
Aug 7, 2010, 12:32:10 AM8/7/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

Well yes, that's a third. I suppose I could have overlooked others as
well.

steve

unread,
Aug 7, 2010, 1:44:53 AM8/7/10
to
On Aug 6, 5:23 pm, nos...@see.signature (Richard Maine) wrote:
> steve <kar...@comcast.net> wrote:
> > That does not answer my question.  AFAIU, the
> > routine cannot be USEd in any other fortran
> > procedure.
>
> False. This sounds like a fairly basic misunderstanding of bind(c).
> Bind(c) does not mean that something cannot be invoked from Fortran. It
> just means that the invocation method is compatible with C.

Thanks for the long explanation.

It has nothing to do with bind(c) other than I got caught
like NAG on the "sequence" issue. It certainly seems
error prone to declare a derived type within the scope
of a contained function and then re-declare that derived
type elsewhere in the code.

> Anyway, if I move the derived type definition out to module scope, where
> I would normally put it if I were writing the code, then the whole thing
> becomes
>
> MODULE liter_cb_mod
> USE ISO_C_BINDING
>      TYPE, bind(C) :: info_t
>         INTEGER(c_int) :: type
>      END TYPE info_t
>
> CONTAINS
>    FUNCTION liter_cb(link_info) bind(C)
>      USE ISO_C_BINDING
>      IMPLICIT NONE
>
>      INTEGER(c_int) liter_cb
>
>      TYPE(info_t) :: link_info
>
>      liter_cb = 0
>
>    END FUNCTION liter_cb
>
> END MODULE liter_cb_mod
>
> PROGRAM main
>   use liter_cb_mod
>
>   type(info_t) :: link_info
>
>   write (*,*) liter_cb(link_info)
>
> END PROGRAM main
>
> which works fine with both Nag and g95 on this machine.
>

The above compiles with gfortran as well. In fact, I
wrote a very similar piece of code before my first
post because I found it odd that one would declare
the derived type in multiple places.

--
steve


Richard Maine

unread,
Aug 7, 2010, 2:06:02 AM8/7/10
to
steve <kar...@comcast.net> wrote:

> It has nothing to do with bind(c) other than I got caught
> like NAG on the "sequence" issue. It certainly seems
> error prone to declare a derived type within the scope
> of a contained function and then re-declare that derived
> type elsewhere in the code.

Agree, which is part of why I wouldn't do it that way. There are other
reasons as well.

As an aside, I'll try to explain why it seems "sensible" that bind(c)
types need to act like this. I can't explain why they aren't called
sequence types, but I can explain why they need act like sequence types.

In essence, C interoperability fundamentally requires that different
declarations count as the same type. There is one declaration in Fortran
and one declaration in C. If those don't count as the same type, then
you wouldn't have interoperability. The only way they can match is by
having appropriately matching properties.

But if a Fortran type matches a C type solely by having the appropriate
properties, even though it is a separate declaration, what if you have
such a Fortran type declared in 2 separate scopes? Both of them would
match the C type just as well, with nothing to establish a preference of
one for the other. Basically, transitivity forces them to match each
other.

Or perhaps consider a slightly different, but less abstract perspective
on the same point. Think about writing some Fortran code designed to
interoperate with a C library. You do so, including definitions of any
necessary bind(c) derived types. Now think about someone else
reimplementing that C library in Fortran. He does so, also including
definitions of any necessary bind(c) derived types. This kind of thing
is supposed to work. As long as both the caller and the callee follow
the rules of C interoperability, they aren't supposed to have to know
what language the other side is implemented in. All they need to know is
the specified C compliant API. That API is not going to include a notion
that if both sides are in Fortran, they have to have shared the same
derived type definition instead of duplicating its properties.

All this can come up in code that does not define argument types within
the subprogram's scope.

glen herrmannsfeldt

unread,
Aug 7, 2010, 3:30:21 AM8/7/10
to
Richard Maine <nos...@see.signature> wrote:
(snip)

> As an aside, I'll try to explain why it seems "sensible" that bind(c)
> types need to act like this. I can't explain why they aren't called
> sequence types, but I can explain why they need act like sequence types.

> In essence, C interoperability fundamentally requires that different
> declarations count as the same type. There is one declaration in Fortran
> and one declaration in C. If those don't count as the same type, then
> you wouldn't have interoperability. The only way they can match is by
> having appropriately matching properties.

Well, another possibility could have been that when you compile
the Fortran module, (or defined type not in a module) it generates
the appropriate C header file. I won't say that would have been
a good choice, though.

More fundamentally, C requires that different declarations of
the same struct are equivalent, usually through an #include file
but they don't have to be done that way.



> But if a Fortran type matches a C type solely by having the appropriate
> properties, even though it is a separate declaration, what if you have
> such a Fortran type declared in 2 separate scopes? Both of them would
> match the C type just as well, with nothing to establish a preference of
> one for the other. Basically, transitivity forces them to match each
> other.

Yes, that.



> Or perhaps consider a slightly different, but less abstract perspective
> on the same point. Think about writing some Fortran code designed to
> interoperate with a C library. You do so, including definitions of any
> necessary bind(c) derived types. Now think about someone else
> reimplementing that C library in Fortran. He does so, also including
> definitions of any necessary bind(c) derived types. This kind of thing
> is supposed to work. As long as both the caller and the callee follow
> the rules of C interoperability, they aren't supposed to have to know
> what language the other side is implemented in. All they need to know is
> the specified C compliant API. That API is not going to include a notion
> that if both sides are in Fortran, they have to have shared the same
> derived type definition instead of duplicating its properties.

Now, why is it that Fortran declarations aren't all sequence type
declarations?



> All this can come up in code that does not define argument types within
> the subprogram's scope.

-- glen

Nick Maclaren

unread,
Aug 7, 2010, 5:37:10 AM8/7/10
to
In article <i3j22c$bph$1...@speranza.aioe.org>,

glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>More fundamentally, C requires that different declarations of
>the same struct are equivalent, usually through an #include file
>but they don't have to be done that way.

You will clearly be surprised to know that is NOT so, but you will
probably never encounter a compiler where they aren't. You MIGHT
hit one of the circumstances where you get an error message, though.
So, in practice, you are effectively correct - but not formally!

That is yet another example where the C standard has conflicting
wording, and where merely reading it will not help with deciding
which wording overrides which other wording.

On my list is to create some interpretation requests in the area of
C Interopability, where Fortran has made assumptions that go beyond
what C specifies.


Regards,
Nick Maclaren.

Richard Maine

unread,
Aug 7, 2010, 12:02:08 PM8/7/10
to
glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> Now, why is it that Fortran declarations aren't all sequence type
> declarations?

I think I'm just going to stop with "because that's the way the votes
came out." Maybe I'll add that I'd have voted the same way (it was well
before my time on the committee, so I didn't actually have the chance),
but I'm not going to try to recite what I recall of the various
arguments for or against.

Nick Maclaren

unread,
Aug 7, 2010, 12:42:21 PM8/7/10
to
In article <1jmuj7v.1t5bkid1j32auaN%nos...@see.signature>,

Richard Maine <nos...@see.signature> wrote:
>glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>> Now, why is it that Fortran declarations aren't all sequence type
>> declarations?
>
>I think I'm just going to stop with "because that's the way the votes
>came out." Maybe I'll add that I'd have voted the same way (it was well
>before my time on the committee, so I didn't actually have the chance),
>but I'm not going to try to recite what I recall of the various
>arguments for or against.

And, if I had been on it, I would have voted against ANY being!

I don't know what arguments were used, but I know a fair number
that could have been (on both sides).


Regards,
Nick Maclaren.

Richard Maine

unread,
Aug 7, 2010, 12:44:09 PM8/7/10
to
Nick Maclaren <n...@gosset.csi.cam.ac.uk> wrote:

> In article <1jmuj7v.1t5bkid1j32auaN%nos...@see.signature>,
> Richard Maine <nos...@see.signature> wrote:
> >glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> >
> >> Now, why is it that Fortran declarations aren't all sequence type
> >> declarations?
> >
> >I think I'm just going to stop with "because that's the way the votes
> >came out." Maybe I'll add that I'd have voted the same way (it was well
> >before my time on the committee, so I didn't actually have the chance),
> >but I'm not going to try to recite what I recall of the various
> >arguments for or against.
>
> And, if I had been on it, I would have voted against ANY being!

Well, now that you mention it, that too. :-)

Dick Hendrickson

unread,
Aug 7, 2010, 2:05:15 PM8/7/10
to
On 8/7/10 11:44 AM, Richard Maine wrote:
> Nick Maclaren<n...@gosset.csi.cam.ac.uk> wrote:
>
>> In article<1jmuj7v.1t5bkid1j32auaN%nos...@see.signature>,
>> Richard Maine<nos...@see.signature> wrote:
>>> glen herrmannsfeldt<g...@ugcs.caltech.edu> wrote:
>>>
>>>> Now, why is it that Fortran declarations aren't all sequence type
>>>> declarations?
>>>
>>> I think I'm just going to stop with "because that's the way the votes
>>> came out." Maybe I'll add that I'd have voted the same way (it was well
>>> before my time on the committee, so I didn't actually have the chance),
>>> but I'm not going to try to recite what I recall of the various
>>> arguments for or against.
>>
>> And, if I had been on it, I would have voted against ANY being!
>
> Well, now that you mention it, that too. :-)
>
No you wouldn't have! ;)

The compelling argument was C versus memory "optimization." People
needed (or at least wanted) to write mixed Fortran/C programs and the
only practical way to do that was have some way to force the compiler to
layout some structures in the C order.

For pure Fortran structures the vendors wanted the flexibility to
reorder elements to prevent memory misalignment. The classic example of
common double, real, other_double
was terribly inefficient on some machines. Allowing the compiler to
re-order the elements-when they were in a structure, not common-let
users define structures in a natural order (especially if they used
computed values for kind specifiers) and still have the possibility of
memory efficiency.

Besides, as someone occasionally points out, sequence and bind(c) aren't
all that different. ;)

Dick Hendrickson

glen herrmannsfeldt

unread,
Aug 7, 2010, 2:14:21 PM8/7/10
to
Nick Maclaren <n...@gosset.csi.cam.ac.uk> wrote:
> In article <i3j22c$bph$1...@speranza.aioe.org>,
> glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

>>More fundamentally, C requires that different declarations of
>>the same struct are equivalent, usually through an #include file
>>but they don't have to be done that way.

> You will clearly be surprised to know that is NOT so, but you will
> probably never encounter a compiler where they aren't. You MIGHT
> hit one of the circumstances where you get an error message, though.
> So, in practice, you are effectively correct - but not formally!

I used to read comp.lang.c, but it takes so long, and I never
really learned much from it. I do remember much discussion of
the "as if" rule, which isn't actually a rule. There is also
the famous case of a compiler that converts between array of
struct and struct of array, such that one program runs much faster.
That case would seem to violate the struct declaration rules.

It would be nice to have an example of the case you are considering.



> That is yet another example where the C standard has conflicting
> wording, and where merely reading it will not help with deciding
> which wording overrides which other wording.

Even so, it seems to work most of the time.



> On my list is to create some interpretation requests in the area of
> C Interopability, where Fortran has made assumptions that go beyond
> what C specifies.

One that I wondered about long ago, but never looked into more,
relates to enum variables and constants. In C, enum constants
are int, even if enum variables are smaller. Also, character
constants are int, though character variables are usually smaller.

With call by value and the usual promotions, this isn't a problem
in C. You can't use the & (address of) operator on constants.
As far as I know, though, Fortran allows passing either as an
actual argument, which would seem to cause problems if not
passed by value.

-- glen

Richard Maine

unread,
Aug 7, 2010, 2:45:47 PM8/7/10
to
Dick Hendrickson <dick.hen...@att.net> wrote:

> On 8/7/10 11:44 AM, Richard Maine wrote:
> > Nick Maclaren<n...@gosset.csi.cam.ac.uk> wrote:
> >
> >> In article<1jmuj7v.1t5bkid1j32auaN%nos...@see.signature>,
> >> Richard Maine<nos...@see.signature> wrote:
> >>> glen herrmannsfeldt<g...@ugcs.caltech.edu> wrote:
> >>>
> >>>> Now, why is it that Fortran declarations aren't all sequence type
> >>>> declarations?
> >>>
> >>> I think I'm just going to stop with "because that's the way the votes
> >>> came out." Maybe I'll add that I'd have voted the same way (it was well
> >>> before my time on the committee, so I didn't actually have the chance),
> >>> but I'm not going to try to recite what I recall of the various
> >>> arguments for or against.
> >>
> >> And, if I had been on it, I would have voted against ANY being!
> >
> > Well, now that you mention it, that too. :-)
> >
> No you wouldn't have! ;)
>
> The compelling argument was C versus memory "optimization."

Really? For f90 (which was when sequence types were introduced)? I
didn't realize C was one of the issues pushing sequence back then. I
thought it had more to do with resistance to modules, as you pretty much
can't use nonsequence types effectively without modules. Throw in people
not wanting to abandon COMMON (yuck) as another part of the same mix.
Not that I was there to hear the debates first hand, but that's the kind
of thing I thought I recalled getting second hand - that people wanted
these derived type things without having to dive more deeply into the
f90 pool of introducing modules and deprecating sequence association and
COMMON.

> People
> needed (or at least wanted) to write mixed Fortran/C programs and the
> only practical way to do that was have some way to force the compiler to
> layout some structures in the C order.
>
> For pure Fortran structures the vendors wanted the flexibility to
> reorder elements to prevent memory misalignment. The classic example of
> common double, real, other_double
> was terribly inefficient on some machines. Allowing the compiler to
> re-order the elements-when they were in a structure, not common-let
> users define structures in a natural order (especially if they used
> computed values for kind specifiers) and still have the possibility of
> memory efficiency.

That would strike me as a really strange basis for argument because
sequence types don't actually disallow reordering and/or padding. If
that were the main reason for debate, one would think that it ought to
connect to something that is actually in the definition of sequence
types.

Only the special cases of numeric and character sequence types have such
restrictions, and those special cases are very restrictive (more so that
one would guess from just seeing the terms). The restrictions on those
cases look a *LOT* more like ones that relate to old f77 stuff than to C
interop. For example, the only integers allowed in numeric sequence
types are default integers. That sounds awfully f77-ish and not at all
C-ish.

The standard's requirements on sequence do pretty much imply that the
rules have to be consistent and based only on the type definition
itself, so that two different but equivalent type definitions will
result in the same layout. But doing things like moving all the doubles
to the front is allowed. You would have to strangely special-case the
ones that fit the requirements of being numeric sequence, but then that
is indeed a strange special case in the standard.

> Besides, as someone occasionally points out, sequence and bind(c) aren't
> all that different. ;)

Yep. And if we didn't have sequence otherwise, one wouldn't have to
explain that bind(c) is a funny way to spell sequence. :-)

Nick Maclaren

unread,
Aug 7, 2010, 2:56:21 PM8/7/10
to
In article <8c5lis...@mid.individual.net>,

Dick Hendrickson <dick.hen...@att.net> wrote:
>On 8/7/10 11:44 AM, Richard Maine wrote:
>>>>
>>>>> Now, why is it that Fortran declarations aren't all sequence type
>>>>> declarations?
>>>>
>>>> I think I'm just going to stop with "because that's the way the votes
>>>> came out." Maybe I'll add that I'd have voted the same way (it was well
>>>> before my time on the committee, so I didn't actually have the chance),
>>>> but I'm not going to try to recite what I recall of the various
>>>> arguments for or against.
>>>
>>> And, if I had been on it, I would have voted against ANY being!
>>
>> Well, now that you mention it, that too. :-)
>>
>No you wouldn't have! ;)

Well, I certainly would have done!

>The compelling argument was C versus memory "optimization." People
>needed (or at least wanted) to write mixed Fortran/C programs and the
>only practical way to do that was have some way to force the compiler to
>layout some structures in the C order.

Which, I regret to say, shows a lamentable lack of understanding of
what the C standard actually says :-(

To be fair, this aspect is so repulsive that few people believe it
even when it is pointed out to them, and the majority of WG14 (even
when I was on it) would have stated that the C standard specified
something that the words did not say.

In my view, the compelling argument is run-time checking. Since
Fortran 66, sequence association has been the number one obstacle
to Fortran compilers implementing any useful bounds checking,
despite the fact that it caused a very high proportion of bounds
errors.


Regards,
Nick Maclaren.

Nick Maclaren

unread,
Aug 7, 2010, 3:23:09 PM8/7/10
to
In article <i3k7ps$bsl$1...@speranza.aioe.org>,

glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>>>More fundamentally, C requires that different declarations of
>>>the same struct are equivalent, usually through an #include file
>>>but they don't have to be done that way.
>
>> You will clearly be surprised to know that is NOT so, but you will
>> probably never encounter a compiler where they aren't. You MIGHT
>> hit one of the circumstances where you get an error message, though.
>> So, in practice, you are effectively correct - but not formally!
>
>I used to read comp.lang.c, but it takes so long, and I never
>really learned much from it.

It was a disaster. There were clued-up posters, but the majority
didn't have a clue - and, I regret to say, that included a fair
number who were on WG14.

> I do remember much discussion of

>the "as if" rule, which isn't actually a rule. ...

Oh, yes, it is. But not in so many words, though I recall it being
in the Rationale. See section 4. Conformance and 5.1.2.3 Program
execution, paragraphs 1, 5 and 9.

>It would be nice to have an example of the case you are considering.

Different declarations have different scopes (in general), and there
is the classic example of using a struct declaration in a parameter
list, which matches no type outside that! And, despite the common
belief, there is NO general requirement that all structs with the
same sequence of types have the same padding.

The only exception to this is when they occur within the same union
(see 6.5.2.3 Structure and union members paragraph 5).

>> That is yet another example where the C standard has conflicting
>> wording, and where merely reading it will not help with deciding
>> which wording overrides which other wording.
>
>Even so, it seems to work most of the time.

As I said, it will. But it's not what the standard says - though
that bears a decreasingly close relationship to reality as time
goes on. C99 got the thumbs down from the IT community, and almost
nobody gives a damn about the planned C1X. Whether C++0X will
change that, because it has implicitly included much of C99 without
actually addressing the problems, God alone knows.

>> On my list is to create some interpretation requests in the area of
>> C Interopability, where Fortran has made assumptions that go beyond
>> what C specifies.
>
>One that I wondered about long ago, but never looked into more,
>relates to enum variables and constants. In C, enum constants
>are int, even if enum variables are smaller. Also, character
>constants are int, though character variables are usually smaller.
>
>With call by value and the usual promotions, this isn't a problem
>in C. You can't use the & (address of) operator on constants.
>As far as I know, though, Fortran allows passing either as an
>actual argument, which would seem to cause problems if not
>passed by value.

It's not a problem. You can't pass constants between the two, not
least because they are conceptually incompatible - in any case, you
can't pass a constant as a C parameter. All such arguments are
variables with the C constant as their value.


Regards,
Nick Maclaren.

M.S. Breitenfeld

unread,
Aug 9, 2010, 11:09:12 AM8/9/10
to
Sorry, it was an oversight on my part in making up my mini-program to
redeclare the type. In the complete program info_t is just used in the
function liter_cb and no where else in the Fortran code (link_info is
only used in the C code, at least for now).

Moving the TYPE declaration to the module scope fixes the compilation
errors with gfortran and Portland Group's compiler as well.

Thanks for all the input.

0 new messages