From: steve on
On Aug 6, 5:23 pm, nos...(a)see.signature (Richard Maine) wrote:
> steve <kar...(a)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


From: Richard Maine on
steve <kargls(a)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.

--
Richard Maine | Good judgment comes from experience;
email: last name at domain . net | experience comes from bad judgment.
domain: summertriangle | -- Mark Twain
From: glen herrmannsfeldt on
Richard Maine <nospam(a)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
From: Nick Maclaren on
In article <i3j22c$bph$1(a)speranza.aioe.org>,
glen herrmannsfeldt <gah(a)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.
From: Richard Maine on
glen herrmannsfeldt <gah(a)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.

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