[J3] Question on iomsg in DTIO

Bader, Reinhold Reinhold.Bader at lrz.de
Mon Apr 1 16:19:33 UTC 2024


Hi Brad, 

I'm attaching an updated version of the draft containing both alternatives, and leave it to /interp to select the 
most appropriate one.
________________________________________
Von: J3 <j3-bounces at mailman.j3-fortran.org> im Auftrag von Brad Richardson via J3 <j3 at mailman.j3-fortran.org>
Gesendet: Donnerstag, 28. März 2024 15:29
An: General J3 interest list
Cc: Brad Richardson
Betreff: Re: [J3] Question on iomsg in DTIO

Hi Reinhold,

But the semantics now do NOT “treat an unallocated iomsg as being not present" anymore. Rather, the semantics are now that an allocatable, deferred length character argument to iomsg is defined "as if by intrinsic assignment", which includes (re)allocation (if necessary). Thus, if the iomsg argument is an allocatable deferred length character a temporary buffer will be needed for the UDTIO procedure whether it is allocated or not. We should make the edits to the standard in such a way that point is made clear.

Regards,
Brad

On Thu, 2024-03-28 at 14:02 +0000, Bader, Reinhold wrote:
Hi Brad,

yes, I wrote the edits to tightly fit the requirement “treat an unallocated iomsg as being not present”. But of course /interp is free to
make changes, especially if the solution below is considered to provide better clarity.

The initial paper could contain an alternative suggestion along the lines below, of course.

Cheers

Von: Brad Richardson <everythingfunctional at protonmail.com>
Gesendet: Donnerstag, 28. März 2024 14:35
An: General J3 interest list <j3 at mailman.j3-fortran.org>
Cc: Bader, Reinhold <Reinhold.Bader at lrz.de>; Malcolm Cohen <malcolm at nag-j.co.jp>
Betreff: Re: [J3] Question on iomsg in DTIO

Hi Reinhold,

When I wrote my earlier response I hadn't quite put together a couple of bits of information. The iostat and iomsg arguments to a UDTIO procedure are not optional, and thus the processor is already obligated to provide them and handle a nonzero iostat value in the case they are not present in the parent IO statement. Given that, I'm fine with the solution that it is the processors job to deal with tying together a deferred length iomsg and a UDTIO iomsg.

However, I think the edits provided are not quite right. If the iomsg argument provided in the parent IO statement is already allocated, it should be reallocated to the size of the message returned by the UDTIO, not that the UDTIO should use its current size. It seems to me the edits provided would indicate the latter. I.e., the behavior if the variable supplied in the parent IO statement is deferred length allocatable should be as if

block
  character(len=PROCESSOR_DEPENDENT) :: iomsg_buffer
  call UDTIO(..., iomsg_buffer)
  iomsg = len_trim(iomsg_buffer)
end block

whether the variable is previously allocated or not.

Regards,
Brad

On Thu, 2024-03-28 at 11:22 +0000, Bader, Reinhold via J3 wrote:
Hi Malcolm, Brad,

thanks for the feedback. Attached an updated draft that tries to follow Malcolm’s suggestion for resolving this issue.
I’ve also updated the discussion a bit since the processor dependencies appear to be a bit too far away from this
scenario.

Cheers,
Reinhold

Von: J3 <j3-bounces at mailman.j3-fortran.org<mailto:j3-bounces at mailman.j3-fortran.org>>Im Auftrag vonMalcolm Cohen via J3
Gesendet: Dienstag, 19. März 2024 04:15
An: 'General J3 interest list' <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>>
Cc: Malcolm Cohen <malcolm at nag-j.co.jp<mailto:malcolm at nag-j.co.jp>>
Betreff: Re: [J3] Question on iomsg in DTIO

Hi Reinhold,

Yes, well we knew when we added auto-reallocation that it was not backwards-compatible.

Brad’s suggestion of allowing allocatable and ordinary arguments to coexist in a generic would need a fair bit of work, as it unfortunately opens the barn doors very wide to ambiguities. It is also not actually necessary to add the full feature *IF* we just want to fix this. And deciding to do this suggestion would be new feature design, and thus Fortran 202y and DATA subgroup.

And the obvious answer here is to treat an unallocated IOMSG= argument as one that is missing. That’s how normal procedure calls work. Yes, the i/o statement is not a “normal procedure call”, but in the end the procedure is “called normally”, so although the words are not explicit (but then much of the new auto-realloc is done by vague handwaving), it is a reasonable deduction.

With that answer, LEN(IOMSG) in the defined i/o procedure would be equal to whatever it is when there is no IOMSG= specifier in the i/o statement. That is already allowed, and the LEN(IOMSG) in the routine is processor-dependent in that case.

Then, to integrate with the new auto-realloc scheme, we just have the processor assign it afterwards (but only with nonzero IOSTAT, of course), allocating it to LEN_TRIM of the returned message (which might have been truncated if the user assigned a ridiculously long message to what is a buffer designed for holding the processor’s i/o messages). The words in the standard already imply this, I think.

The main thing missing would appear to be an explicit description of what an unallocated allocatable means for defined i/o. The rest is, I think, already there.

I note that this solution is not one of your suggested resolution. However, it is, I think, what the features we have imply should happen. As has happened so often in the past, we added a new feature but neglected to describe it hyper-rigorously because “we all know what it means”, and thus missed out describing it properly.

Cheers,
--
..............Malcolm Cohen, NAG Oxford/Tokyo.

From: J3 <j3-bounces at mailman.j3-fortran.org<mailto:j3-bounces at mailman.j3-fortran.org>>On Behalf OfBader, Reinhold via J3
Sent: Monday, March 18, 2024 8:03 PM
To: General J3 interest list <j3 at mailman.j3-fortran.org<mailto:j3 at mailman.j3-fortran.org>>
Cc: Bader, Reinhold <Reinhold.Bader at lrz.de<mailto:Reinhold.Bader at lrz.de>>
Subject: [J3] Question on iomsg in DTIO

Dear all,

attached a draft paper for which I’d like some feedback (especially from /interp) before I submit it to the J3
site.

Cheers
Reinhold


-------------- next part --------------
To: J3                                                     J3/##-###
From: Reinhold Bader
Subject: interp request for iomsg in DTIO procedure
Date: 2024-Mar-20
References: 20-122, 24-007

Introduction
~~~~~~~~~~~~

With Fortran 2023, restrictions on iomsg variables were removed, so a 
deferred-length string passed into a I/O statement by the user would 
be allocated to the needed length.
This paper poses the question what happens if the I/O statement
has been overloaded by a DTIO procedure.

Example
~~~~~~~

Consider the following program:

MODULE mod
   TYPE :: t
      INTEGER :: i
   END TYPE

   INTERFACE WRITE(FORMATTED)
      MODULE PROCEDURE wf
   END INTERFACE
CONTAINS
   SUBROUTINE wf(dtv, unit, iotype, v_list, iostat, iomsg)
      CLASS(t), INTENT(in) :: dtv
      INTEGER, INTENT(in) :: unit, v_list(:)
      CHARACTER(len=*), INTENT(in) :: iotype
      INTEGER, INTENT(out) :: iostat
      CHARACTER(len=*), INTENT(inout) :: iomsg

      iostat = 129
      iomsg = 'Sorry, wf only pretends to be a DTIO procedure'

   END SUBROUTINE
END MODULE
PROGRAM p
   USE mod
   TYPE(t) :: o = t(4)
   INTEGER :: ierr
   CHARACTER(len=:), ALLOCATABLE :: msg

   WRITE(*,*, iostat=ierr, iomsg=msg) o ! (Y)
   IF (ierr /= 0) THEN
       WRITE(*,*) ierr, len(msg), msg ! (X)
   END IF
END PROGRAM

Questions
~~~~~~~~~

(Q1) does the program conform to the standard?
(Q2) if it conforms, what is the value of len(iomsg) inside the 
    procedure wf?
(Q3) if it conforms, what will the statement marked (X) print?

Discussion
~~~~~~~~~~

On the face of it, it would seem that the answer to (1) 
must be "yes", since the clearly stated intention of
20-122 is that the appearance of an allocatable msg in 
statement (Y) should imply its allocation as needed. 
On the other hand, there seems to be no way how the 
implementor of a DTIO procedure can account for this 
situation, since the dummy argument iomsg simply does not 
have the ALLOCATABLE attribute.
Note, though, that if iomsg= does not appear at all on the parent
I/O statement, the situation is similar; different from other
argument's characterizations (e.g., v_list) in 12.6.4.8.3, there 
are no words on what the processor provides for iomsg=. There
does exist a processor dependency, but that seems to apply only
in the case that error termination is initiated, which would not
be the case in the scenario outlined above.


Suggested resolution
~~~~~~~~~~~~~~~~~~~~

(A1) Yes, the intention was that this program should conform.
     Edits are supplied to cover missing semantics of iomsg=
     in DTIO procedures.
     
(A2) The length of the iomsg string will have a processor-dependent
     value.
     
(A3) Assuming that the processor-dependent value for the length of the
     iomsg dummy argument is at least 46, the output would be something 
     like
     
     129  46  Sorry, wf only pretends to be a DTIO procedure
     
     
Suggested edits to 24-007:
~~~~~~~~~~~~~~~~~~~~~~~~~~

Two alternatives are presented below. The first one regards
the unallocated case as being non-present and therefore requiring
processor-dependent handling inside the DTIO procedure; the second
one considers the appearance of an allocatable iomsg= to generally 
require processor-dependent handling inside the DTIO procedure.  

Alternative 1
=============

In 12.6.4.8.3 Executing defined input/output data transfers, 
insert new para at the top of page 258 (before para 10):

"If the parent I/O statement specifies an iomsg= of defined length, 
 the processor shall supply an iomsg= dummy argument of that length; 
 otherwise, its length has a processor-dependent positive value."
 
In the current para 10 on that page, after

"return an explanatory message in the iomsg argument", add

"; an unallocated allocatable iomsg= appearing in the parent I/O 
 statement will be subsequently allocated to hold the number of leading 
 non-blank characters in the dummy argument, and with the value 
 represented by this sequence of characters"  
 
In 12.11.6 IOMSG= specifier, para 1, after "is assigned an explanatory 
message", replace "as if by intrinsic assignment" by

"; this is done as if by intrinsic assignment, unless a defined 
 input/output procedure was executed (12.6.4.8.3)."
 

Alternative 2
=============

In 12.6.4.8.3 Executing defined input/output data transfers, 
insert new para at the top of page 258 (before para 10):

"If the parent I/O statement specifies a nonallocatable iomsg=, 
 the processor shall supply an iomsg= dummy argument of the length
 of that variable; otherwise, the dummy argument's length has a 
 processor-dependent positive value."
 
In the current para 10 on that page, after

"return an explanatory message in the iomsg argument", add

"; an allocatable iomsg= appearing in the parent I/O statement will be 
 subsequently allocated or reallocated to hold the number of leading 
 non-blank characters in the dummy argument, and with the value 
 represented by this sequence of characters"  
 
{no edit needed for 12.11.6 in this alternative}


More information about the J3 mailing list