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===