With pgfortran 18.10, the following code results in a warning.
use, intrinsic :: iso_c_binding
integer(c_int) x
type(c_ptr) y
y=c_loc(x)
end
The warning is
PGF90-W-0468-Argument to ISO_C_BINDING intrinsic must have TARGET attribute set
This is unhelpful for two reasons:
A TARGET attribute is not necessary: a POINTER attribute suffices
The function c_loc in the module iso_c_binding is not an intrinsic function. It would also be better to use the name rather than being vague (especially when wrong).
Equally, we can see the error message
PGF90-S-0155-Intrinsic not supported in initialization: c_loc
with the obvious change. Again, c_loc is not intrinsic.
I talked with our compiler folks about this but they’re a bit confused by your comments.
The Fortran 2008 language specification states that the argument to C_LOC “shall have either the POINTER or TARGET attribute� (see section 15.2.3.6 C LOC (X) in the Fortran 2008 language specification, paragraph 3 on the argument). There is similar language in the Fortran 2018 specification.
So if anything, we should be issuing an error rather than a warning here.
The NAG and Gfortran compilers both generate an error in this case.
Intel does not issue an error nor a warning.
For example:
% gfortran test.f90
test.f90:5.8:
y=c_loc(x)
1
Error: Parameter 'x' to 'c_loc' at (1) must be either a TARGET or an associated pointer
The simple solution is to add target to x’s declaration.
% cat test.f90
use, intrinsic :: iso_c_binding
integer(c_int), target :: x
type(c_ptr) y
y=c_loc(x)
end
% gfortran test.f90
% pgfortran test.f90
%
The example I gave was certainly not a valid Fortran program, and the compiler is allowed to handle it as it chooses. Yes, I’d prefer this to be recorded as an error, but ifort and pgfortran are entitled to issue a warning or nothing and accept the program.
A better document for a discussion is the Fortran standard. For example, Fortran 2018 describes “intrinsic” as:
Consider the (non-standard) program:
implicit none
print*, c_loc(1)
end program
Unsurprisingly, pgfortran 18.10 rejects this program:
The function c_loc is not accessible without being use associated.
Further, the standard explicitly states:
The module iso_c_binding where c_loc sits is, of course, an intrinsic module.
We’re still a bit confused about the complaint and what actions you would like us to take. We read your initial post as a complaint about the compiler issuing a warning but upon your clarification post you seem to be more at issue with the text of the warning rather than the warning itself?
Keep in mind that warning and error messages must be short and concise as well as convey the to the user a basic understanding of the issue. They are not meant to give a full explanation of a problem. Common terms and edits for brevity may be used.
Hence, a more technically correct message such as:
PGF90-W-0468-Argument to the transformational function C_LOC in the ISO_C_BINDING intrinsic module must have a TARGET or POINTER attribute set
Would be way too long for a warning message, so was condensed. The omission of “POINTER” was most likely done was since adding “TARGET” is the simplest change to the code to avoid this issue. Using “POINTER” will change the properties of the variable such as how it’s passed as an argument.
Would adding a detailed explanation here be an acceptable resolution to your complaint? Or do you have suggested text for this warning message that would better convey the issue?
As for the question of whether C_LOC is an intrinsic or not. Intrinsic here is meant more as being provided by the compiler implementation. As you point out that this does not match the exact phrasing as listed in the Fortran 2018 standard’s definition for “intrinsic”. Although not technically correct, since C_LOC is part of the ISO_C_BINDING intrinsic module and provided by the compiler implementation, it is often thought of and commonly referred to as an intrinsic.
Of course, we are open to suggestions. Would you prefer the error message called c_loc a “tranformational function” instead? Though, I’ve also seen it refereed to as an “inquiry function” as well.
My apologies if this wasn’t clear the first time, but yes: my thoughts were on the content of the message not whether there should be a message (as a warning or error).
If I were writing the message I’d probably go for something like: “Argument to C_LOC must have POINTER or TARGET attribute”.
I looked at what error message pgfortran gives when a disallowed intrinsic transformational function is used in an initializer:
integer :: i=>command_argument_count()
end
PGF90-S-0087-Non-constant expression where constant expression required
This would also cover the case of trying to use C_LOC (as C_LOC cannot appear in a constant expression)?
Failing that if you’d like to be more helpful to the user, how about “Non-intrinsic [transformational] function C_LOC where constant expression required” or “Disallowed function where constant expression required: C_LOC”, etc.?
Of course, you’ve now considered my concerns, so if you’d prefer to keep things as they are then that’s fair enough.