This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Bind(C) with optional arguments


Hello,

John McFarland wrote:
> I have noticed that gfortran does not allow BIND(C) for a procedure
> with an optional argument, e.g.:
>
> subroutine sub(x) bind(c)
>   integer, optional :: x
> end subroutine sub
>
> I have two questions (I'm assuming that the Fortran 2003 standard
> disallows this,

It does. In Fortran 2003 it is constraint C530, in the latest Fortran
2008 draft it is C516:

"The ALLOCATABLE, POINTER, or OPTIONAL attribute shall not be specied
for a dummy argument of a procedure that has a proc-language-binding-spec."

> but correct me if I'm wrong).  My first question is whether anyone
> knows if there are plans to allow this in a future version of the
> standard (it seems useful).

I agree that it is useful. The answer is yes. It is planned to be part
of the technical report (TR 29113) "Further interoperability of Fortran
with C". An early draft can be found at
ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1808.pdf (see Section 2.3 for
your request). However, the document will still see many modification.
The objective of the TR can be found at
ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1820.txt (note: this document
is newer than the draft N1808 above!) Regarding the schedule for
finalizing/publishing the TR, see item 4 at
ftp://ftp.nag.co.uk/sc22wg5/N1801-N1850/N1812.txt - you see, it will
still take a while.

> My second question is whether it would be unsafe to use the optional
> argument mechanism without explicitly declaring BIND(C) (i.e. by
> passing a NULL pointer from C to indicate the argument is not present).

Yes and no. GNU Fortran - and many other compilers - use a NULL pointer
internally to denote an absent optional argument; however, there might
be compilers which do not. Additionally, if you skip the BIND(C)
attribute, you modify the procedure interface - or at least the
procedure name. With bind(C), you can fine-tune the procedure name as
you want. Without, you get the default - and especially for module
procedures, the "binding" name is a bit ugly. Another thing which
changes is the way strings are passed: Without bind(C) there is a
trailing hidden argument with the string length.

The proper but admittedly ugly way is to pass a TYPE(c_ptr), use
c_associated as NULL check and convert it then to a Fortran pointer via
c_f_pointer. You should really consider doing this instead of the
system-specific way you do below.

[Question was whether unsafe to use:]
> subroutine sub(x)
>   integer, optional :: x
>   if (present(x)) print*, x
>
> // From c:
> #define sub __MOD_m_sub
> x = 5;
> sub(NULL); // call without optional arg
> sub(&x); // call with optional arg

I think that should be "safe" in the sense that it matches what gfortran
effectively does itself. However, it is highly unportable (procedure
name "__MOD_m_sub") and ugly.

> Specifically, I am wondering if the PRESENT intrinsic could ever
> return an incorrect result in this situation, where either a NULL
> pointer (to indicate not present) or a valid pointer (to indicate
> present) is passed from C.

Well, Fortran allows to combine VALUE with OPTIONAL, which of cause
cannot be handled like that. (And gfortran currently does not handle at
all.) But otherwise, it should work.

Tobias


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]