ISO/IEC JTC1/SC22/WG5 N1853 Edits made to N1849 to create N1854. Bill Long, 31 May 2011 References (WG5 Documents): N1849 - TR 19113 Working Draft N1853 - (This paper) N1854 - The updated TR 19113 Draft. This paper documents changes made to N1849 based on the comments submitted during a review of N1849 done by email using the interop-tr email list, and an editorial review. The updated document is N1854. The paper is divided into two parts: 1) List of edits made in citation order, with editorial comments. Includes edits that were rejected by reason of being redundant with an edit proposed by someone else. 2) Collection of edits and issues which are still open for discussion. Identifiers for individual proposed edit citations, enclosed in {...} on the initial lines of edits: CER - Craig Rasumssen (USA, DOE) JKR - John Reid (UK, WG5 Convenor) NM - Nick Maclaren (UK, Cambridge) MC - Malcolm Cohen (UK, NAG) RB - Reinhold Bader (Germany, LRZ) TB - Tobias Burnus (Germany, gfortran) Ed - Bill Long (USA, Cray, TR Editor) Edits identified as {Ed} without "comment" represent edits added by the Editor for the reason indicated in the edit. All page and line number citations are to N1849. ================================= Part 1 - Edits to N1849. -------------------------------- -[iv:Foreword]----------------{MC, Ed} {Ed: The way to typeset the name of our ancestor committee in the Forward seems inconsistent.} MC: You should compare with the standard, where they are consistent. {Ed: Last line of p1: "ISO/IEC JTC 1" {one / and space between C and 1}} MC: Yes. {Ed: First line of p5: "ISO/IEC/JTC1" {two / and no space}} MC: That one is wrong then. {Ed: First line of p7: "ISO/IEC JTC1" {one / and no space}} MC: Ditto. MC: Ok, the Foreword needs more work... you need two new paragraphs after p3, here is some sample text taken from a recent (2010) TR: p3a: In exceptional circumstances, the joint technical committee may propose the publication of a Technical Report of one of the following types: -- type 1, when the required support cannot be obtained for the publication of an International Standard, despite repeated efforts; -- type 2, when the subject is still under technical development or where for any other reason there is the future but not immediate possibility of an agreement on an International Standard; -- type 3, when the joint technical committee has collected data of a different kind from that which is normally published as an International Standard ("state of the art", for example). p3b: Technical Reports of types 1 and 2 are subject to review within three years of publication, to decide whether they can be transformed into International Standards. Technical Reports of type 3 do not necessarily have to be reviewed until the data they provide are considered to be no longer valid or useful. In your p5, you should delete the (E), and insert at the same place ", which is a Technical Report of type 2," In p7, I think you should probably strike "/WG5"; there is no mention of WG5 anywhere else, we are doing the work on behalf of SC22. -[3:17+]-----------------{RB, JKR, Ed} Add a constraint to ensure that assumed-type actual arguments have dope vector information if they correspond to a dummy that requires a dope vector. [3:17+] Add a constraint "C407c An assumed-type actual argument that corresponds to an assumed-rank dummy argument shall be assumed-shape or assumed-rank." {Ed: Same edit at [24:17+].} -[4:16-17]-----------------{Ed} A big part of the TR facility is to allow dummy arguments with the OPTIONAL, ALLOCATABLE, or POINTER attributes. See page v, para 2. Yet, we have a subclause heading "2.3 OPTIONAL attribute", but none for allocatable or pointer. They are just covered by text in the OPTIONAL subclause. We should have text similar to [4:17-18] that explicitly says ALLOCATABLE and POINTER are allowed. A couple of modifications to 2.3 seem like candidates: Option 1: [4:16] Replace "OPTIONAL attribute" with "ALLOCATABLE, OPTIONAL, and POINTER attributes". [4:17] Replace "OPTIONAL attribute" with "ALLOCATABLE, OPTIONAL, and POINTER attributes". Option 2: [4:23+] Insert a new subclause heading and paragraph: "2.4 ALLOCATABLE and POINTER attributes The ALLOCATABLE and POINTER attributes may be specified in a procedure interface that has the BIND attribute." {Ed: All of those responding preferred Option 1. That was implemented.} -[5:18]--------------------{Ed} The text at [5:18] is not literally correct. Proposed fix: [5:18] Before "C descriptor" insert "pointer to a ". -[9:4]-----------------{Ed} The list of things C descriptors can describe in [9:4] does not match the corresponding list at [9:14-15] in that "assumed character length" is omitted at [9:4]. Probably an earlier omission. Also the order does not match in the two places. Edit: [9:4] Replace "assumed-shape, assumed-rank, allocatable" with "allocatable, assumed character length, assumed-rank, assumed-shape". -[10:2-3]-------------------{MC email} [10:2-3] Replace "the C address of the element for which ... corresponding lower bound" with "the C address of the first element". -[10:18]------------------{MC} [10:18] "a data pointer, allocatable, assumed-shape, or assumed-size" -> "allocatable, assumed-shape, assumed-size, or a data pointer" {Better grammar since the article only applies to one of the list items.} -[10:21]---------------------{Ed} I think it would be clearer to add "dim" before "array" at the beginning of the description of the dim argument. It is a normal sentence and there is some ambiguity as to what "the array" is. Edit: [10:21] Before "array" insert "dim". -[10:25]---------------------{MC} [10:25] "allocatable or pointer array" -> "array pointer or allocatable array". {Correct terminology: "pointer array" is often understood by many people to mean an array of pointers.} -[10:27-29]-----------------{NM, JKR} The current wording does not state that all of the sm values must be greater than the element length. It definitely needs saying! [10:29] Change "previous dimension" to "previous dimension, and the smallest absolute value of the sm member is not less than the elem_len member of the descriptor". Following email discussion, settled on this version from JKR instead: Replace [10:27-29] with: "There shall be an ordering of the dimensions such that the absolute value of the sm member of the first dimension is not less than the elem_len member of the descriptor and the absolute value of the sm member of each subsequent dimension is not less than the absolute value of the sm member of the previous dimension multiplied by the extent of the previous dimension." -[10:29+]----------------------{JKR} Add "NOTE 5.0 The reason for the restriction on the absolute values of the members is to ensure that there is no overlap between the elements of the array that is being described, while allowing for the reordering of subscripts. Within Fortran, such a reordering can be achieved with the intrinsic function TRANSPOSE or the intrinsic function RESHAPE with the optional argument ORDER, and an optimizing compiler can accommodate it without making a copy by constructing the appropriate descriptor whenever it can determine that a copy is not needed." {Ed: Moved to [10:32+] to follow the style of putting Notes at the end of a subclause.} -[10:32+]--------------------{Ed} In Note 5.1 the "character" looks like the name of a Fortran type, so should be upper case. Edit: [12:Note 5.1] Make "character" upper case. -[11:5+]---------------------{TB} In Table 5.1, change the code entry in for the first macro from "assumed" to "assumed shape". {Ed: The old "assumed" made more sense before we added "assumed size.} -[11:7-8]--------------------{MC} [11:7-8] "an assumed-shape object or a scalar that is not allocatable or a pointer" -> "an assumed-shape or nonallocatable nonpointer scalar object" OR -> "an assumed-shape object or a nonallocatable nonpointer scalar". {Clearer to use non-a non-p than "is not a or a p".} {Ed: Used second option.} -[13:6]---------------------{MC} [13:6] "allocatable objects" -> "an allocatable object". {Use singular as per ISO guidelines.} -[13:6]---------------------{MC} [13:6] "through execution" -> "by execution". {I believe "by" is the best preposition to use here.} -[14:4-10]------------------{RB} [14:6-10]: gcc gives me a warning here: warning: assignment makes integer from pointer without a cast I suggest the following changes [14:4] "real" -> "real(c_float)" Revised [14:6-10]: CFI_index_t subscripts[2]; float *address; subscripts[0] = 10; subscripts[1] = 10; address = (float *) CFI_address( dv, subscripts ); as well as pointing out that *address resolves to the value of a(10,10). {Ed: made code changes. the "pointing out..." seemed redundant with the current line 5, so did not make that change.} -[14:8-9]-------------------{RB} [14:8-9] must be changed to subscripts[0] = 9; subscripts[1] = 9; -[15:2,6,22,23]------------{CER} [15:2,6,22,23] Change "flag" to "ind". {Consistent with other examples.} -[15:30-31]-----------------{MC} [15:30-31] "If it points to a C descriptor that describes an allocatable object, the object shall be unallocated." -> "It shall not point to a C descriptor that describes an allocated allocatable object." {Seems clearer, and uses a similar sentence structure as the previous sentence to describe the prohibition.} -[15:37]-------------------{Ed} The current description for the type argument to CFI_establish says it shall be one of the type names in Table 5.2. But the argument is not a "name", but a type code denoted by one of the macros. Edit: [15:37] Replace "type names" with "type codes". -[16:8]--------------------{MC} [16:8] "assumed-length character object" -> "assumed character length object" {Use the correct Fortran term.} -[16:9]--------------------{MC} [16:9] "an unallocated allocatable, or a pointer" -> "an unallocated allocatable object, or a data pointer". {The first two items in this list are "... array, ... object" so it makes me expect to see "object" after "allocatable". And we do only mean data pointers here IIANMM.} -[16:19,24]-----------------{Ed} In Example 1 for CFI_establish, the dim argument is not used, so there is no point in it being declared. It might even be confusing if the reader thinks it is needed. Edits: [16:19] Delete line. [16:24] Replace "dim" with "NULL". -[16:25-43]----------------{Ed, TB, JKR, RB} Based on the observation by TB that Example 2 for CFI_establish is very close to the example for CFI_select_part, alternatives were considered. The most popular option was this: Replace the current text at [16:25-43] with a modified example thus: "Example 2: For the Fortran array a declared thus: type,bind(c) :: t REAL(C_DOUBLE) x complex(C_DOUBLE_COMPLEX) y end type type(t) a(100) the following code fragment establishes a C descriptor for the array a(:). typedef struct { double x; double complex y;} t; CFI_dim_t dim[1]; CFI_CDESC_T(1) source; int ind; dim[0].lower_bound = 0; dim[0].extent = 100; dim[0].sm = sizeof(t); ind = CFI_establish ( (CFI_cdesc_t *) &source, &a, CFI_attribute_assumed, CFI_type_other, sizeof(t), 1, dim );" -[17:5-6]---------------------{NM, MC} {Ed: Discussion related to the result value of CFI_is_contiguous.} As it stands, it states that it returns 0 if the descriptor is not valid. That might not matter if it were not for the fact that some other calls allow descriptors to be passed in anomalous states. [17:5-6] Delete: "the descriptor pointed to by the dv argument is a valid C descriptor and". A related suggestion from JKR: "Would it not be a good idea to make CFI_is_contiguous and CFI_address return error indicators? That would bring them into line with all the other functions." did not get consensus, and I think there are usability arguments for leaving the current interfaces. So this was not changed. -[17:9]--------------------{JKR} Change 17:9 to " Establishes a C descriptor for an array section for which each element is an element of a given array." Reason: The text should say what kind of section is intended and parallel the text for CFI_select_part. It would also make the details that follow easier to understand. -[17:13-14]---------------{MC} [17:13-14] Same edit as [15:30-31] for the same reason. -[17:16]------------------{MC} [17:16] "pointer" -> "array pointer". {Since allocatable scalars are prohibited - only allocatable arrays are allowed - for consistency this should prohibit scalar pointers as well.} -[17:24]-----------------{JKR} At 17:24 Change "an array" to "the array". Reason: the array is uniquely defined by the descriptor. -[17:8-39]----------------{RB, JKR, Ed, CER} The basic problem addressed with these edits is that the CFI_section function does not provide a means to specify where the array section starts within the source array. The solution it to use the dim argument to specify this information. The lower_bounds member of each dim element specifies the corresponding subscript in the source array that is the first element of the result array. If the result rank is smaller than the source rank, the dimensions collapsed out have an extend of -1. [17:8] Delete "CFI_rant_t rank," [17:18-19] Delete rank argument [17:20-21] Replace the first two sentences of the dim description with: "dim points to an array specifying the subset of the given array that forms the array section. The number of elements shall be source->rank. The lower_bound members specify the subscripts of the element in the given array that is the first element of the array section. [17:23] Replace "." by "; for each dimension for which a subscript is specified in the section subscript, the corresponding extent member of dim shall have a value of -1." [17:26] Add at end of para 3: "The value of result->rank is source->rank minus the number of dim entries for which the extent member is equal to -1." [17:30] After "array A" add "declared as real A(100)". [17:31] Change "A(1:10:5)" to "A(3:10:5)". [17:33] Delete line. [17:36] Replace line with "dim[0].lower_bound = 2;" [17:39] Delete "rank," -[18:3]------------------{JKR} At 18:3. Change "an array" to "an array section". Reason: The term "array section" is used in the details that follow. {Ed: Make 18:3 change at 18:24 also} -[18:8-9]-----------------{MC} [18:8-9] Same edit as [15:30-31] for the same reason. -[18:11]------------------{MC} [18:11] "pointer array" -> "array pointer". {Correct terminology.} -[18:13-14, 16-17]--------{JKR} At 18:13-14 & 16-17. Delete "described by the C descriptor pointed to by result" twice. Reason: type and displacement are input arguments and result need not point to a C descriptor on input. -[18:15]------------------{CER} [18:15] Change "is the value to be added" to "is the value in bytes to be added". -[18:20-22]---------------{JKR} At 18:20-22. Change "object" to "array section" thrice. Reason: "object" is ambiguous. -[19:1]-------------------{JKR} At 19:1. Change to " CFI_setpointer updates a C descriptor for a Fortran pointer to point to the whole of a given object or be disassociated." Reason: The text should say more about what is intended. It would also make the details that follow easier to understand. -[19:6, 14-15]-------------{MC, Ed} Straw vote question: Should CFI_setpointer be allowed to set the result to be a disassociated pointer if source is an unallocated allocatable? The analog in Fortran is not allowed. Yes, leave as is. 1 vote. No, disallow an unallocated allocatable source. 5 votes. ==> Disallow the unallocated allocatable case. Edits: [19:6] In the description of the source argument, before "allocatable" insert "allocated". [19:14-15] Remove "an allocatable object that is not allocated or". {The final sentence reads, after including another edit from MC: "If source is NULL or points to a C descriptor for a disassociated pointer, the updated C descriptor describes a disassociated pointer."} -[19:8]-------------------{TB} [19:8] Change "not greater than zero" to "zero". {Ed: This change seems reasonable. The only places where rank can be set are in functions where the value of rank is required to be non-negative. If the descriptor became corrupted to the point of having a negative rank, the CFI_INVALID_RANK error could be returned. Similar change at [16:6].} -[19:8]-------------------{JKR, Ed} The lower_bounds are (I assume) ignored if source is NULL. [19:8] Change "if the rank" to "if source is NULL or the rank". -[19:14]--------------------{MC, Ed} [19:14] "allocatable object that is not allocated" ->"unallocated allocatable object". {Seems clearer.} {Ed: The text at [19:14] was removed by a different edit. This edit not made.} -[19:18]------------------{JKR, Ed} The description in para 6 does not make sense if source is NULL. [19:18] Change "If lower_bounds is NULL" to "If source is not NULL and lower_bounds is NULL". -[19:15, 18-19]------------{JKR, Ed} Replace 19:18-19 with the following, appended to the end of 19:15: "Otherwise, the C descriptor pointed to by result becomes a C descriptor for the object described by the C descriptor pointed to by source, except that the lower bounds are replaced by the values of the lower_bounds array if the rank is greater than zero and lower_bounds is not NULL." ============================= Part 2: Open Issues: -------------------- -[15:28-30]-------------------{CER} Page 15, line 28-30: The text "It shall not point to a C descriptor that describes an object that is described by a C descriptor pointed to by a formal parameter that corresponds to a fortran dummy argument" has to many level of indirection to be understandable. I suggest that "It shall not point to a C descriptor corresponding to a C formal parameter." means the same thing and is easier to understand. This usage appears elsewhere. {Ed: Multiple comments were received about this sentence. It might be better to have a single statement of restrictions in 5.2.6 that would allow this sentence to be removed or greatly simplified.} -[various]--------------------{TB} {Ed: This section replies to a six comments / questions submitted by TB. I don't believe any of the issues remain "open", but wanted to document the responses.} (1) p.10, parag. 3 [24:25]: "For a descriptor of assumed-shape array, the value of the lower-bound member of each element shall be zero." Why is it zero and not one as in Fortran? I would expect that the lower bound mainly matters for CFI_Address calculations - and I had expected that having there the Fortran bounds would be more logical. If one does direct pointer arithmetic, one starts a [0], but then in many cases one does not need lower_bound information at all. I assume that for a Fortran procedure with BIND(C), the lbound(assumed_shape) remains 1? {Ed: MC replied to this issue: The LBOUND of a Fortran assumed-shape array is not 1 unless that is what the user asks for (or accepts the default). An assumed-shape array-spec is ( [lower] : [ , [lower] : ]... ) i.e. the lower bounds are specified by the called procedure: it is assumed-shape, not assumed-bounds.} (2) p. 10, parag. 3 [27:29] I have a some difficulties to digest that paragraph. Maybe, one should add note that the dim order is the standard Fortran order. At least I believe that's what the paragraph is telling me. {Ed: The purpose of that paragraph is to require that a particular element of the array cannot be referenced by more than one valid set of subscripts. The paragraph was modified by other edits in Part 1 of this paper.} (3) {Ed: (3) became the Edit at [11:5+].} (4) p. 14, Sect. 5.2.5.3. CFI_allocate for CFI_attribute allocatable: Shouldn't one require that dv->base_address is NULL? Or if not, will there be a CFI_BASE_ADDR_NOT_NULL error if not? {Ed: The corresponding part of the base standard, [129:2-3] specifies that you get an error for trying to allocate an object that is currently allocated. There is not a "shall be unallocated" requirement. The intent is to have the same semantics for CFI_allocate. So, your second alternative is the correct one - the return value will be CFI_BASE_ADDR_NOT_NULL.} (5) {Ed: (5) became the Edit at [16:25-43].} (6) {Ed: (6) became the Edit at [19:8].} -[31:32-33]------------------{Ed} The Annex example A.1.3 was previously deleted from N1845 because it was no longer allowed by subsequent changes. This place holder remains. Consensus was not achieved in the email discussions on a replacement.