Janne Blomqvist wrote:
On Fri, Dec 28, 2012 at 12:31 AM, Tobias Burnus <bur...@net-b.de> wrote:
a) The Fortran standard only defines LOGICAL(kind=C_Bool) as being
interoperable with C - no other LOGICAL type. That matches GCC: With gcc
(the C compiler) only _Bool is a BOOLEAN_TYPE with TYPE_PRECISION == 1.
Hence, this patch rejects other logical kinds as dummy argument/result
variable in BIND(C) procedures if -std=f2003/f2008/f2008ts is specified
(using -pedantic, one gets a warning).
Sorry, I don't understand, what is the -pedantic warning about if it's
already rejected? Or do you mean std=gnu -pedantic?

The latter. Actually, I use "gfc_notify_std(GFC_STD_GNU, ..." and just observed the -pedantic result. (I have to admit that I never quite understood - and still don't - what -pedantic exactly does.)

b) As GNU extension, other logical kinds are accepted in BIND(C) procedures;
however, as the main use of "LOGICAL(kind=4)" (for BIND(C) procedures) is to
handle logical expressions which use C's int, one has to deal with all
integer values and not only 0 and 1. Hence, a normal integer type is used
internally in that case. That has been done to avoid surprises of users and
hard to trace bugs.
Does this actually work robustly?

I think it does in the sense that it mitigates the problems related to LOGICAL(kind=4) and BIND(C) procedures. No, if one thinks of it as full cure for the problem. The only way to ensure this is to turn all of gfortran's LOGICALs into integers - and even that won't prevent issues related to interoperability with C's _Bool as that one expects only 0 and 1. Thus, either C<->Fortran or Fortran <-> Fortran logical(kind=C_Bool) could still lead to problems.

E.g. if you have a logical but really integer under the covers, what happens if you 
equivalence it with a "normal" logical variable.

Well, equivalencing of actual arguments / result variables is not allowed (I think, not checked). Besides, if you have equivalenced two variables, if you have set one, you may not access the other, e.g.:

logical :: A
integer :: B
equivalence (A,B)
A = .true.
B = 1
if (A) ...

is invalid as "A" is not defined, even if A = .true. and B = 1 have exactly the same storage size and bit patterns and, hence, in practice "A" would be a well defined .true.

Or pass it as an argument to a procedure expecting a normal logical etc.

If the value is only 1 or 0, there shouldn't be any problems. Only if one uses in turn ".not. dummy" there might be one.

The idea of the patch was only to mitigate the problems - a full cure is not possible (cf. above). I think the most likely problematic code is
   if (.not. c_function())
which is fixed by the patch. And the hope is that fold-converting to a type-precision=1, Boolean-type logical fixes most of the remaining issues.

I think the current solution which only affects non-C_BOOL-kind actual arguments and result variables of BIND(C) procedures is a good compromise.

* * *

But if others do not like this approach, one could turn the gfc_notify_std into a gfc_error are completely reject logicals with kinds /= C_Bool for dummy arguments/result variables in BIND(C) procedures. Would you prefer that approach?

(Doing so will break user code (e.g. Open MPI) and make users unhappy but it will be a tad safer as the current patch.)

Tobias

Reply via email to