12-190
To: J3
From: Malcolm Cohen
Subject: Revised answer/edits for C_PTR and BIND.
Date: 2012/10/16
----------------------------------------------------------------------
NUMBER: F03/0053
TITLE: The BIND attribute for C_PTR and C_FUNPTR
KEYWORDS: BIND attribute, C_PTR, C_FUNPTR, private components
DEFECT TYPE: Erratum
STATUS: Passed by J3 letter ballot
QUESTION:
1. Do the derived types C_PTR and C_FUNPTR have the BIND attribute?
This affects whether an object of one of these types is permitted
directly in COMMON. C5101 in the Fortran 2008 standard states "If a
common-block-object is of a derived type, it shall be a sequence type
or a type with the BIND attribute and it shall have no default
initialization."
2. Whether the derived types C_PTR and C_FUNPTR have the BIND
attribute affects whether they are extensible. Subclause 4.5.7.1 of
the Fortran 2008 standard states "A nonsequence derived type that does
not have the BIND attribute is an extensible type." Are these types
extensible?
3. Subclause 15.3.3 of the Fortran 2008 standard states that C_PTR and
C_FUNPTR are derived types with private components. Are user-defined
derived types with the BIND attribute permitted to have private
components?
ANSWER:
1. No, these types do not have the BIND attribute. 15.3.3 does not
specify that they have the BIND attribute. 15.3.4 does not require
them to have the BIND attribute in order to make them interoperable.
15.3.5 would require them to interoperate with a C struct if they had
the BIND attribute; this is absurd, since C object pointers and C
function pointers are clearly not structs.
Note that whether these types have default initialization is not
specified by the standard, so possession of BIND would not necessarily
have allowed them in COMMON anyway.
Edits are provided to correct incomplete, and thus misleading,
statements about derived types and the BIND attribute.
2. No, these types were not intended to be extensible. It was an
oversight that these types were not explicitly excluded from being
extensible by subclause 4.5.7.1 paragraph 1 of the Fortran 2008
standard. An edit is provided to correct this.
3. Yes, a user-defined derived type with the BIND attribute is
permitted to have private components. This situation is the same
as for SEQUENCE types, which are similar (but not interoperable).
As with SEQUENCE types, making a component PRIVATE does prevent
access, in a conforming program, to the component by a programmer who
is sufficiently determined; however, it continues to fulfill the
software engineering role for which it was intended. Note further
that there are many other situations where two different Fortran
derived types will interoperate with the same C derived type; this is
not a defect in either standard, but simply a consequence of the two
languages having different approaches to type compatibility.
EDITS to 10-007r1:
[19:15-16] In 1.3.147.6,
replace the definition of "extensible type"
with "type that may be extended using the EXTENDS clause (4.5.7.1)".
{Repair definition of extensible type.}
[77:3] In 4.5.7.1p1,
After "A derived type" insert
", other than the type C_PTR or C_FUNPTR from the intrinsic module
ISO_C_BINDING,"
{Prohibit these types from subsequent extension.}
[431:6] In 15.3.4p1, replace entire paragraph with
"Interoperability between derived types in Fortran and struct types
in C is provided by the BIND attribute on the Fortran type."
{Reduce misleading opening blather - this is just here so we didn't
start the subclause with a bunch of constraints. Alternatively we
could move paragraph 2 (and note 15.12) to replacce paragraph 1.}
[431:12+2] In 15.3.4, Note 15.11,
After "is interoperable" insert "with a C struct type".
{Correct another misleading sentence.}
[431:13-18] In 15.3.4p2,
Change all four occurrences of "Fortran derived type"
to "derived type";
change the single occurrence of "Fortran type" to "derived type".
{Remove unnecessary and confusing qualification of "derived type" with
"Fortran".}
SUBMITTED BY: John Reid
HISTORY: 05-151 m171 F03/0053 submitted - Passed by J3 meeting
05-170 m172 Passed J3 letter ballot #11
N1622 m172 Failed WG5 ballot N1629
11-217r1 m195 Revised answer for Fortran 2008 - Passed
by J3 meeting
11-241 m196 Passed as amended by J3 letter ballot
#24 11-229
12-165r2 m198 Passed by J3 letter ballot #25 12-147
N1939 m198 Failed WG5 ballot N1933
12-190 m199 Revised answer and edits
----------------------------------------------------------------------
Comments and reasons for NO votes
F03/0053
Bader NO vote:
I agree with John Reid that it should be explicitly stated that
the above types do not have the BIND attribute.
Corbett NO vote:
I agree with John that allowing private components in
derived types that have the BIND attribute seems absurd.
Long NO vote:
Regarding answer 3, I think it would be better to disallow
PRIVATE components in a type with the BIND attribute. A C routine
called outside the module where the type is defined, and accessing a
variable of such a type would be able to access and modify the PRIVATE
components.
Maclaren comment:
A better solution would be to state that, notwithstanding the general
rules for derived types, they do have the BIND attribute and are
interoperable with C variables of type 'void *' and 'void (*) ()',
respectively. This matter should be addressed in a future revision, but
it might be easier to do that now than make the current situation
consistent.
I also agree with John Reid on question (2), and regard the liberty to
break the privacy restrictions by using interoperability as a defect in
the standard. And, yes, I agree that it would be fine to do that for
SEQUENCE, too. But both would be changes to the standard.
Reid NO vote:
1. I remain of the opinion that 15.3.3 should state clearly that
C_PTR and C_FUNPTR do not have the BIND attribute. It is counter-
intuitive that they are interoperable and yet do not have the
BIND attribute. They are defined in an intrinsic module so
the reader cannot look at the definition. The present text relies
on the distinction between "derived type" in 15.3.3 and "Fortran
derived type" in 15.3.4. The term "Fortran derived type" is
undefined and is not used anywhere else in the standard (as far
as I can see). The text of 15.3.3 is similar to 15.2.2 in the
Fortran 2003 standard. In N1622, J3 thought it was unclear and
proposed editing 15.2.2 to say that these types do have the BIND
attribute. I suggest the edit:
[431:2] 15.3.3, para 1. At the end of sentence 1 add
"and without the BIND attribute".
2. Was it really intended that a user-defined derived type with
the BIND attribute be permitted to have private components?
It seems to me that this should not be permitted since it
destroys the purpose of declaring components to be private.
If it was intended, the rationale should be included in the
answer - this is, after all, an interpretation.
....................................................................
F03/0053: Replies from the editor
- it is a fundamental principle that entities only have the attributes that
the standard says they have. We do not say the integer 13 does not have the
BIND attribute. We do not even say that derived types defined with no BIND(C)
clause do not have the BIND attribute! We should strenuously resist putting
more unnecessary blather into the standard.
Oh, and at max this is "friendly witter". Inserting witter is not necessary
for defect correction. In fact my opinion is that this kind of thing is not
friendly at all but is harmful to comprehension, because it means that in
every other case where we don't say an entity "does not have (laundry-list of
attributes)", the reader will be misled into thinking that maybe it might. No.
No. No. Just don't do it.
And especially there is no case for doing it via interp.
<<<
It is counter-intuitive that they are interoperable and yet do not have
the BIND attribute.
>>>
Not so; plenty of things are interoperable and do not have the BIND attribute.
For an example of another type that is interoperable but does not have the BIND
attribute, see INTEGER(c_int).
<<<
They are defined in an intrinsic module so
the reader cannot look at the definition.
>>>
There is, in fact, no derived-type definition, any more than there is a secret
INTERFACE block for any generic intrinsic. A derived-type definition is a piece
of Fortran syntax in the program, and therefore cannot be exist in anything
intrinsic.
<<<
The present text relies on the distinction between "derived type" in 15.3.3
and "Fortran derived type" in 15.3.4.
>>>
No it does not. I do not know where this bizarre idea comes from.
<<<
The term "Fortran derived type" is undefined and is not used anywhere
else in the standard (as far as I can see).
>>>
It is not an undefined term, it is plain English. Grr. I understand why the
authors of that text thought it was useful to drop a few "Fortran" hints in case
the reader got the idea they might have been using a C term, but IMO it was
unnecessary (it has confused John at least!).
<<<
The text of 15.3.3 is similar to 15.2.2 in the Fortran 2003 standard.
In N1622, J3 thought it was unclear and proposed editing 15.2.2 to say
that these types do have the BIND attribute.
>>>
I dispute this account. Though N1622 is ancient history and not relevant
anyway.
The point is that J3 was confused about whether THEY INTENDED for these types
not to have the BIND attribute. There was no confusion in my mind, or likely
in other /DATA or /INTEROP members, as to what the standard actually said,
the question was entirely whether this was a mistake or not!
And if the answer was ever going to be that they had the BIND attribute, of
course an edit was needed as you point out, because in the absence of an edit
they do NOT have the BIND attribute, any more than 42_c_int does.
<<<
2. Was it really intended that a user-defined derived type with
the BIND attribute be permitted to have private components?
>>>
Yes, by analogy with SEQUENCE. In fact BIND is very very like SEQUENCE, the
only real difference being a potential difference in alignment padding.
<<<
It seems to me that this should not be permitted since it
destroys the purpose of declaring components to be private.
>>>
Then we had better prohibit PRIVATE from SEQUENCE types, because it has
Precisely The Same Effect there, and has done since 1991.
We Are Not Going To Do That.
(Aside: we don't even prohibit non-SEQUENCE non-BIND(C) types with PRIVATE
components in the TRANSFER intrinsic, so this idea that PRIVATE is some kind
of impermeable electric fence has never been correct.)
<<<
If it was intended, the rationale should be included in the
answer - this is, after all, an interpretation.
>>>
No rationale is required for this any more than for any other part of the
standard. It has the normal rationale "it got voted in". You don't get us to
write 1000 lines after class if you don't like the answer, that is no more
reasonable than it would be for me to demand to hear from you why everyone
voted for SEQUENCE+PRIVATE back in the day...
J3 has consistently voted against any kind of rationale document. There is no
case to answer here.
Nick writes:
> I also agree with John Reid on question (2), and regard the liberty to
> break the privacy restrictions by using interoperability as a defect in
> the standard.
Well good then, because you cannot "break the privacy restrictions" that way.
The user cannot put BIND(C) on the derived types in the library he is calling.
If it's his own library, *HE CAN DO ANYTHING HE LIKES ANYWAY*.
The Fortran PRIVATE attribute has never ever been this super-restrictive thing
that you and John are imagining. For SEQUENCE types (and thus BIND(C) types)
there are multiple ways of "seeing past the curtain", in these cases all
PRIVATE does is to hide the name when accessing things of the type outside of
a module with a definition. This is not as useful as PRIVATE on an extensible
type, but still has some uses.
Once again, with feeling: BIND(C) is merely the interoperable version of
SEQUENCE, and therefore has basically the same allowances and limitations as
SEQUENCE. There is no defect here.
===END===