To: J3 J3/17-246 From: Steve Lionel Subject: ERRMSG= and deferred-length allocatable character Date: 2017 October 17 Reference: 17-007r2, 10-007r1 Introduction ------------ In Fortran 2008, the (then new) ERRMSG= specifier, used in ALLOCATE and DEALLOCATE, was described as follows: [132:23-25, 6.7.5p2] If an error condition occurs during execution of an ALLOCATE or DEALLOCATE statement, the processor shall assign an explanatory message to errmsg-variable. If no such condition occurs, the processor shall not change the value of errmsg-variable. In the Fortran 2015 draft, this paragraph reads: [147:26-28, 9.7.5p2] If an error condition occurs during execution of an ALLOCATE or DEALLOCATE statement with an ERRMSG= specifier, the errmsg-variable is assigned an explanatory message, as if by intrinsic assignment. If no such condition occurs, the definition status and value of errmsg-variable are unchanged. The Fortran 2015 draft also extends ERRMSG= to image control statements; the description of this is: [218:30-32, 11.6.11p12] If an ERRMSG= specifier appears in an image control statement and an error condition occurs, errmsg-variable is assigned an explanatory message, as if by intrinsic assignment. If no such condition occurs, the definition status and value of errmsg-variable are unchanged. Note the addition of "as if by intrinsic assignment"; this has an interesting effect if the errmsg-variable is deferred-length allocatable character. Discussion ---------- Consider the following program: character(:), allocatable :: errmsg_var real, allocatable :: arr(:) integer :: status ! Assume that an attempt to allocate an array of HUGE(0) elements ! fails and that the error message the processor provides is ! "Out of memory" errmsg_var = "initial" ! Allocates errmsg_var to length 7 ALLOCATE (arr(HUGE(0)), STAT=status, ERRMSG=errmsg_var) PRINT *, status, errmsg_var !A DEALLOCATE(errmsg_var) ALLOCATE (arr(HUGE(0)), STAT=status, ERRMSG=errmsg_var) PRINT *, status, errmsg_var !B END Intrinsic assignment to a deferred-length allocatble character variable is described in 10.2.1.3. In case A, the length of the message (13) is different from the errmsg-variable's length (7), so the variable would be deallocated and then reallocated to length 13 before assignment. In case B, the variable is not allocated so it would get allocated to length 13. Is this what was intended? Fortran 2008 did not say "as if by intrinsic assignment", so the issue did not arise - a reasonable implementation could assume that the variable was already allocated and would use the normal character assignment rules (padding or truncation). It is likely that the words were added to attempt to clarify this, but they open up an additional action that may not have been intended. A further complication is that 9.7.5p1 says, "The errmsg-variable shall not be allocated or deallocated within the ALLOCATE or DEALLOCATE statement in which it appears". While this was intended to prohibit errmsg-var from appearing as an allocate-object, it conflicts with the rules of intrinsic assignment. There are two possible approaches to resolve this: 1) Decide that it was intended that deferred-length allocatable character variables would get (re)allocated to the length of the message and amend 9.7.5p1 to narrow the restriction to appearance of errmsg-var as an allocate-object. This is more user-friendly, as it relieves the programmer of preallocating the variable to some, perhaps unknown, maximum length. Note that this would be a new feature in Fortran 2015 and would require a note in the introduction. 2) Decide that reallocation was not intended and modify 9.7.5 and 11.6.11 to require that the variable be treated as if errmsg-var was followed by (:) to inhibit reallocation. This goes against the typical use of deferred-length character variables. Suggested Edits to 17-007r2 --------------------------- Approach 1 - reallocation allowed [xviii, Introduction] Add to "Data Usage and Computation": "deferred-length allocatable character variables used with ERRMSG= get allocated to the message length" [147:22-23, 9.7.5p1] Replace "The errmsg-variable shall not be allocated or deallocated within the ALLOCATE or DEALLOCATE statement in which it appears" with: "The errmsg-variable shall not be an allocate-object or a subobject of an allocate-object within the ALLOCATE or DEALLOCATE statement in which it appears" Approach 2 - reallocation not allowed Wording for this is complicate by the fact that errmsg-variable could be a variable with a substring - the suggested wording here is not to imply that errmsg-variable would be followed by (:) but that it is "as if" such an assignment were done. [147:27, 9.7.5p2] After "as if by intrinsic assignment" insert "to a variable-name followed by (:)" [218:31, 11.6.11p12] After "as if by intrinsic assignment" insert "to a variable-name followed by (:)"