Comments on N1570/N1572 (ISO/IEC DIS 24772-8:2025) from Dan Bonachea, LBNL (SC22/WG5 and INCITS/Fortran) General: This is the first time I've seen 24772-8:2025, so apologies that my significant feedback was not registered sooner. Overall I found this to be a very valuable document; I read it carefully and even learned a few interesting things. A few places are slightly out-of-date with respect to changes expected in the forthcoming Fortran 2028 standard, but I assume that's out-of-scope for this revision of the document. Below are my suggestions for improving 24772-8:2025, ordered and grouped by subclause: ---------------------- 4.9 Polymorphism p2: "The existing procedure usually has a dummy argument of the type that is given the pass attribute. A type-bound procedure is invoked as if it were a component of the object; if the procedure has an argument with the `pass` attribute, the corresponding actual argument is omitted from the argument list and the invoking object is passed automatically. Here is an example:" (ge) This setup prose leaves the reader expecting to see a `pass` attribute in the example code, but the (optional) `pass` attribute has been entirely omitted from the example. I believe this is still correct (as it relies on a default behavior), but nevertheless it's very confusing, especially without an explanation of the defaulting. Suggest either adding an explicit `pass` attribute in the code, or alternatively a comment/sentence explaining that it's implicit in this case. ---------------------- 4.10.2 Locks p1: "A lock is a scalar variable of the derived type lock_type that is defined in the intrinsic module iso_fortran_env." (ed) Technically the correct terminology used by the standard is "lock variable", not "lock" (multiple instances throughout this paragraph). However this is a minor point and can perhaps be ignored if the goal is informal understanding. "Fortran requires a lock to be a scalar coarray or an element of a coarray." (te) This statement is false (or at best misleading). In fullest generality, a lock variable is permitted to be an allocatable component in an array coarray of derived type, eg: `LOCK (coarray(i)[img]%foo%lock)` (see F2023 16.10.2.19, C1608). As such, it would be better to rephrase this sentence as something like: "Fortran requires a lock variable to be a coarray or an element or component of a coarray." It also seems asymmetric to make this point about `lock_type`, but not about `event_type` or `notify_type`, which have exactly analogous constraints (C1604, C1612). Unless it's somehow relevant (does not appear to be), then perhaps it's better to just drop this sentence entirely? ---------------------- 4.10.3 Teams p1: "Teams are sets of images; a team is expected to execute independently of other teams." (te) Everything after the ; is basically nonsense. A team does not execute, it is an ordered set of images which execute. In general every image is simultaneously a member of multiple teams, and there is no "expectation" regarding how an image executes based solely on team membership. IMHO drop everything after the semicolon. SM I think we can remove everything after the semicolon without changing technical meaning. (ge) This section also notably fails to mention the `sync team` statement, despite 4.10 introducing every other `sync` image control statement in the language. Suggest adding something like: "The `sync team` statement synchronizes all the images in a given team." 4.10.1 introduces the "sync" statement in its various forms. I think we can add that statement into 4.10.1 with a forward reference to 4.10.3 without damaging anything. ---------------------- 4.10.4 Segments p1: "Any statement that implies ordering between the execution of statements on different images is known as an image control statement." (te) This is a rather poor definition of "image control statement" (ICS). In particular, some image control statements (e.g. `sync memory`) do not, on their own, imply ordering across images. Similarly other operations (e.g., atomics, `notify wait`) can be used to imply ordering across images, but are not themselves an ICS. It would perhaps be better to say something like: "Image control statements are statements that define the boundaries of segments, which are statement execution sequences on an image. Some image control statements additionally synchronize between images and thus establish ordering of execution between images." However this phrasing also has some overlap with paragraph 2. SM We are not attempting to define Fortran in this document, only to catch relative issues to describe how programs can be compromised. ---------------------- 4.10.4 Segments p3: "If the value of a variable or a part of it is altered in a segment, it is permitted to be referenced in another segment only if the two segments are ordered, or if the variable is: — integer of kind atomic_int_kind or logical of kind atomic_logical_kind (see 4.10.5); — asynchronous (see 4.10.6 Asynchronous variables); — volatile (see 4.10.7)." (te) The first list item is misleading and technically false. It is not the kind parameter that exempts a variable from the segment access rules (see F2023 11.7.2), it is atomic subroutine invocations that are exempt. Suggested replacement: - defined or referenced by an atomic subroutine (see 4.10.5); (te) The second and third list items are Just Plain Wrong. The asynchronous and volatile attributes do NOT exempt a coarray from the access prohibitions between unordered segments (see F2023 11.7.2). The asynchronous and volatile attributes govern behavior *within* an image with respect to accesses outside the Fortran processor (e.g. from a device or actions of the companion processor), they do not impart license to ignore the (cross-image) segment ordering requirements for conforming coarray accesses. Delete both the second and third list items. (ge) There are two other exceptions to the standard's segment ordering rules (F2023 11.7.2) that are currently omitted from the list: > An event variable or notify variable may be referenced or defined during the execution of a segment that is unordered relative to the execution of another segment in which that event variable or notify variable is defined. > A variable defined in an unordered segment only by execution of an assignment statement with a NOTIFY= specifier may be referenced or defined after execution of a NOTIFY WAIT statement that satisfies that assignment statement execution. One could possibly summarize these with two new list items: - of type `event_type` or `notify_type` - defined by assignment statement with a `notify=` specifier and subsequently referenced or defined after execution of a corresponding `notify wait` statement However note that none of `event_type`, `notify_type`, `notify=` or `notify wait` are currently introduced in 4.10, so that would probably also need to be added to remain self-contained. ---------------------- 4.10.5 Atomic actions p1 (te) typo: "The system insures ..." => "The system ensures ..." ---------------------- 4.10.6 Asynchronous variables p1: "Another exception of the segment ordering rule is that a variable can be declared as asynchronous." (te) This sentence makes a technically inaccurate statement regarding Fortran's segment ordering rules (see comment above on 4.10.4 Segments p3). Suggested replacement: "A variable can be declared or associated with the asynchronous attribute." ---------------------- 4.10.7 Volatile variables p1: "A further exception for the segment ordering rule is that a variable can be declared as volatile." (te) This sentence makes a technically inaccurate statement regarding Fortran's segment ordering rules (see comment above on 4.10.4 Segments p3). Suggested replacement: "A variable can be declared or associated with the volatile attribute." ---------------------- 6.3.1 Applicability to language [STR] p4-5: "These values can be assigned to named constants thereby providing a name for a mask. Such constants can be placed in an integer aligned to the right using the int intrinsic, for example: i = int(o’716’,kind(i)). If the size of I is 8 bits, then the final value becomes o’316’, not o’716’, as the user intended." (ge) As written this example has processor-dependent behavior, a distraction which dilutes the point this section is trying to make. After bit-level truncation to 8 bits, the 8-bit sequence for o’316’ is `11001110`. The standard for 16.9.110 INT (A [, KIND]) states: > Case (vi): If A is a boz-literal-constant, the value of the result is the value whose bit sequence according to the > model in 16.3 is the same as that of A as modified by padding or truncation according to 16.3.3. > The interpretation of a bit sequence whose most significant bit is 1 is processor dependent. As per the last sentence, the current example has processor-dependent behavior, because the sign bit is set in the 8-bit sequence, and the standard does not require twos-complement integer representation. It would be better to change the example to instead read: i = int(o’516’,kind(i)). which (when `i` is an 8-bit kind) results in truncation to o'116`, and is guaranteed to assign the value positive decimal 78 (instead of 334 as the programmer might have expected). ---------------------- 6.17.2 Avoidance mechanisms for language users [NAI] p1: "-- disable implicit typing by using the implicit none statement;" (ge) This is good advice, but enforcement is error-prone (i.e. it's easy to forget the `implicit none` statement, and non-trivial to audit comprehensively). Better advice would be to use compiler options, where available, to globally disable implicit typing entirely. For example, gfortran and LLVM flang both provide an `-fimplicit-none` compiler option that globally enforce explicit typing. Other popular compilers have similar options. This might technically be covered by "the avoidance mechanisms of ISO/IEC 24772-1:2024 6.17.5;", but it still seems worth emphasizing that such checking is easily available in popular Fortran compilers. (ge) Same comment also applies to 6.18.2 [WXQ], 6.19.2 [YZS], 6.21.2 [BJL], 6.54.2 [BRS] and 7.2.2; all of which currently recommend the `implicit none` statement, but fail to mention that Fortran compiler options are usually available to deploy global enforcement of explicit typing without source code changes. ---------------------- 6.51 Pre-processor directives [NMP] p1-3: "The C pre-processor, as defined by the C language, is unaware of several Fortran source code properties." (ed) The C language (ISO/IEC 9899:2024) does NOT define a "pre-processor". It defines a "preprocessor" (no hyphen). This spelling was apparently inherited from ISO/IEC 24772-1:2024 6.51 and incorrectly propagated throughout this document's section 6.51. IMHO we should not propagate that misspelling into this document, or at least not when referring specifically to the C language preprocessor. ---------------------- 6.59.1 Applicability to language [CGA] p3: "To ensure that all images have activated successfully, the insertion of a sync all statement with an iostat= specifier provides the check. If the sync all statement detects a failed image, all images can be terminated by any image executing an error stop statement. ... at the start of the program insert a sync all statement with an iostat= specifier to ensure that all images have activated successfully. " (ed) The `sync all` statement does not have an "iostat=" specifier. The specifier meant is called `stat=`, and should be corrected in both places. (ge) Also, there's no need to actually provide the `stat=` specifier for this purpose, because as specified in F23 11.7.11: > If an error condition occurs during execution of an image control statement that does not > contain the STAT= specifier in a sync-stat, error termination is initiated. Meaning it's sufficient to invoke `sync all` without specifiers to ensure error termination if there are any failed images. This is both more concise and less error-prone than passing an explicit `stat=` specifier. ---------------------- 6.61.1 Concurrent data access [CGX] p1: "Data are accessible across image boundaries: ... — by invoking a procedure that has an image selector in square brackets." (te) This list item looks to me like AI slop; procedures never have image selectors. Fortran does not have remote procedure call, and procedure pointers are prohibited from being communicated across images (see F2023 C854, C915, C918, C1030). If something else is meant here then significant clarification is called for. Otherwise this list item should probably be deleted. ---------------------- 6.61.1 Concurrent data access [CGX] p2: "For all coarray data, Fortran provides mechanisms for serializing the alteration of the value of a variable on one image from its access by another image: — the sync all and sync images statements (4.10.1); ... — teams (4.10.3); " (ge) This list should mention `sync team` somewhere, for symmetry with `sync all` and `sync images`. For example, the "teams" list item could perhaps be changed to something like: — the `form team` and `sync team` statements and the `change team` construct (4.10.3); Same section, same list: "— collectives (4.10.8)." (te) This list item is highly misleading and IMO should simply be deleted. Collective subroutines are not image control statements, they are never guaranteed to synchronize images and they do not order segments. Collective subroutines are often used as an *alternative* to communication through coarrays, but they are mostly orthogonal to coarray data (coarrays are permitted as an argument to a collective subroutine, but passing them does not impart special semantic treatment by the standard). ---------------------- 6.61.2 Avoidance mechanisms for language users [CGX] p1: "use the sync_all statement ..." (ed) Spelling error: `sync all` "use the sync_images statement ..." (ed) Spelling error: `sync images` (ge) The mechanism list should probably also mention the `sync team` statement, either together with `sync all` or as a separate list item. "use the event post statement in one image and the corresponding event wait statement on another image to impose sequential ordering" (ed) typo: "in one image" should be "on one image" (ed) "sequential ordering" should probably be "segment ordering" (i.e., `event post` -> corresponding `event wait` provides ordering between two specific segments, which is weaker than what is generally meant by the undefined term "sequential ordering") ----------------------