integer, target :: x = 123
function foo() result(p)
integer, pointer :: p
p => x
integer function bar(q)
integer, pointer :: q
bar = q
print *, bar(foo())
Note the absence of INTENT(IN) on the dummy argument q.
Conforming, or not? Every compiler under the sun accepts this program, but I believe that they all are incorrect. My thinking, which may of course be wrong, is that in the context of an actual argument expression, the reference to the function foo() is a “variable”, namely the target of the returned pointer, and not the pointer itself. Unlike the case of a “data-target” in a pointer assignment statement, there’s no special carve-out in actual argument specifications for references to functions whose results are data pointers. (And maybe there should be such a special case, but I can’t find one in F’2018.)
Per Fortran standard, a reference to a data pointer is always to a defined target that is associated with said pointer. Such a reference being disallowed when the pointer is not associated with a valid target. So the first sentence in the above quote doesn’t appear relevant to the question in the original post from what I understand.
When it comes to the second sentence involving INTENT(IN), my view is it applies to the automatic targeting facility introduced in Fortran 2008 when the actual argument has the TARGET attribute whereas the corresponding dummy argument has the POINTER attribute; again not relevant here according to my understanding.
For the code in the original post, the function reference foo() in bar( foo() ) function reference appears to be a variable which is a valid data pointer in the scope of foo. Thus in foo, it should
conform to have, say, a pointer assignment q => y where y is some valid target. Say y is defined as 42, the PRINT statement in the main program should then output 42. The standard seems to indicate as such and other compilers appear to agree.
As to a cover from the standard though, perhaps someone else will post here that will be readily accepted as an argument from authority to immediately yield such a thing.
It may well need an interp to sort out (i.e. insert the right language to make current usage by compilers correct) but I can’t believe the committee intended to disallow use in this context as a pointer (because it is easy enough to get to the target if that’s what was wanted).
I am not attempting to declare authority, but I agree with @FortranFan that the example is conforming.
First, consider 15.3.3 Characteristics of function results (emphasis mine):
The characteristics of a function result are its declared type, type parameters, rank, whether it is polymorphic, whether it is allocatable, whether it is a pointer, whether it has the CONTIGUOUS attribute, and whether it is a procedure pointer
Therefore, foo() is a pointer. The interface to bar specifies that the dummy argument q is a pointer. (As @FortranFan correctly notes, the relevance of intent(in) applies only when the corresponding actual argument is not a pointer.)
I understand the uncertainty, especially given 9.2p1:
A variable is either the data object denoted by designator or the target of the pointer resulting from the evaluation of function-reference; this pointer shall be associated.
but I think the context of the use is important. 184.108.40.206p3 says:
A present pointer dummy argument that corresponds to a pointer actual argument becomes argument associated with that actual argument.
The actual argument is a pointer, so the dummy is associated with it.
I’d be open to clarifying this somehow, but I’m not sure what would work here.
Note that INTENT(IN) for a pointer dummy variable only means that the pointer association status of that pointer cannot be changed in the procedure. The value of the target of the pointer can be changed.
The OP is asking about standard conformance. A different question is whether one should ever write a function returning a pointer result. Richard Maine said no in comp.lang.fortran 8 years ago
Now my personal recommendation is to assiduously avoid ever using
functions that return pointers. I am quite serious about wishing that
they had not even been introduced into the standard. Use a subroutine
and pass the pointer back via an argument instead. Functions that return
pointers are EXTREMELY error prone. Even experts mess them up at
times. I find it instructive that there was at least one case of someone
here posting an example of such a function that he considered a “safe”
kind of use, but actually had one of the common errors because he was
concentrating on other aspects and missed that error. He even knew
better than that error, but it is an easy one to make anyway.
Unfortunately, some of the common errors are of types that do not tend
to get caught at compile time, but instead cause confusing run-time
When smart people say never use feature X it simplifies my life, if not that of compiler writers.
I fail to see “special” language in the standard or a “special carve-out” of relevance to the primary inquiry about conformance in the original post. As mentioned upthread, Fortran 2008 introduced a pointer function reference in any variable-definition context and it’s as simple as that.
Arguably there are a few remnants in the current publication from prior revisions (90, 95, 2003) left over from the time when a pointer function reference was disallowed in a variable definition result that could perhaps do with better phrasing if the standard editor had infinite time and infinite other resources, but I fail to see anything that fundamentally would alter the interpretation offered here.
I would not term it as “special” language or “special” carve-out. BNF and C1025 in current standard appears a less verbose and, dare I say simplified, text of what was there with Fortran 2003. Anyways, the motivating rationale for that particular BNF and constraint might simply be the paired semantics of POINTER <=> TARGET that was meant to provide a more secure way for working with pointers in Fortran toward scientific and technical programs. This is as opposed to anything with actual arguments with function result references.
I fail to see how 19.6.7(10) is relevant here; 19.6.7(10) refers to the situation when the actual argument is a procedure as opposed to a function result reference, the latter being simply a data-pointer vis-a-vis the original post.
Malcolm Cohen has written to me with a comment on this. He seems to accept that there is a contradiction in the Standard which will be addressed. It is worth pointing out his usual procedure for similar issues: was the code conforming in earlier standards (yes, for F2003) and if so, is it explicitly mentioned in, for instance, “4.3.4 Fortran 2003 compatibility” that the code is no longer conforming (it is not mentioned). We can then assume that the intention was that the code conforms to F2018 and that will be the interpretation decision.