[J3] Elemental and optional arguments
John Reid
John.Reid at stfc.ac.uk
Sun Jun 27 10:17:26 UTC 2021
José,
José Rui Faustino de Sousa via J3 wrote:
> Dear All,
>
> I would be very much obliged if anyone could kindly answer a few
> questions about the correct interpretation of the standard.
>
> I am confused by the interplay of optional arguments and elemental
> procedures specially under the definition of presence in 15.5.2.12.
>
> Even more so by the possibility that a function will return an array
> or a scalar depending on an argument, which is graphically present,
> being considered absent under 15.5.2.12.
The standard has no concept of "graphically present". 15.5.2.12
defines the meaning of "present" and uses it.
> I think my confusion is mostly caused by my difficulty in
> understanding the purpose of the restrictions placed by the standard
> on references to elemental procedures and without understanding
> purpose rules just seem arbitrary and hard to follow.
>
> From what I could understand I wrote this list of, possibly wrong,
> assumptions:
>
> First of all I am assuming that all the issues raised by elemental
> procedures must be resolved at compile time, except for the extents
> which may only be known at runtime. Although I don't think this is
> explicitly stated in the standard it is a core characteristic of the
> language.
No, we can get runtime errors here.
>
> Second I am assuming that there are two perspectives to actual
> argument presence, in the sense of 15.5.2.12. The perspective from the
> procedure which has an optional argument, which cannot know why an
> argument is not present, and the perspective from the subprogram which
> makes the procedure reference, which knows if the argument is
> graphically present or not.
>
> (I understand 15.5.2.12.3 (6) to apply only in the first perspective.)
I do not recognize your idea of "perspective". Whether a dummy argument
is present is defined by 12.5.2.12. 15.5.2.12.3 (6) refers to an
optional argument of the procedure that is calling the elemental procedure.
>
> A corollary of these two assumptions would be that shape conformance
> of graphically present actual arguments is mandatory, without regard
> to presence in the sense of 15.5.2.12, and reduces to rank matching.
No.
>
> Third, although AFAIK this is not stated anywhere, I am assuming that
> what the standard is trying to enforce is that, at compile time, it
> must be possible to know if a reference to an elemental procedure will
> be an elemental reference, which will need scalarization, or a
> "normal" scalar procedure reference.
Yes. If an array argument is absent, another array argument must be
present, see 15.5.2.12.3 (6).
>
> Forth I am assuming that it is possible and legal to define elemental
> procedures that obey all the rules stated in 15.9.1, but that
> afterwords cannot be elementally referenced, at least under some
> circumstances.
Yes, as illustrated by the program you sent.
>
> Fifth, in the case of functions, I am assuming that the LHS of the
> function assignment does not play any role on deciding if a reference
> to an elemental function is an elemental reference or not.
Agreed.
>
> (This makes techniques like return value optimization hard to apply.)
>
> Sixth, in the case of functions and although AFAIK this is not stated
> anywhere, I am assuming that in a reference to an elemental function
> which is not an elemental reference, even if the LHS is an array, the
> function should only be evaluated once.
I don't see why you need any words for this case. We have a scalar
expression and an array lhs.
>
> Are these assumptions correct?
>
> As an illustration I add a small program:
>
> program emess_p
>
> implicit none
>
> integer :: i
> integer, parameter :: n = 11
> integer, parameter :: u(*) = [(i, i=1,n)]
>
> integer, allocatable :: a(:)
> integer :: b(n)
> integer :: cnt
>
> cnt = 0
> b = efun()
> if(any(b/=1)) stop 1
> if(cnt/=1) stop 2
> cnt = 0
> ! In principle it is only possible to know if a is present at runtime,
> ! so this is most likely illegal. Although I don't know why has I
> ! don't think 15.5.2.12.3 (6) applies here.
> b = efun(a)
You have a runtime error here because a is not allocated and therefore
regarded as absent.
> if(any(b/=1)) stop 3
> if(cnt/=1) stop 4
> allocate(a, source=u)
> cnt = 0
> b = efun(a)
> if(any(b/=u)) stop 5
> if(cnt/=n) stop 6
> stop
>
> contains
>
> impure elemental function efun(a) result(b)
> integer, optional, intent(in) :: a
>
> integer :: b
>
> cnt = cnt + 1
> if(present(a))then
> b = a
> else
> b = 1
> end if
> return
> end function efun
>
> end program emess_p
>
> Thank very much for your time.
>
> Best regards,
> José Rui
I hope this helps.
John.
More information about the J3
mailing list