Unhelpful warning/error messages with C_LOC

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.

Hi iabpab,

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
%

Also, c_loc is an intrinsic. See: Intrinsic procedures in Fortran Wiki

Hope this helps,
Mat

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.

Hi iabpab,

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.

For fuller explanations, we do document some of the error and warning messages in our Reference Manual (Reference Manual :: PGI version 18.10 Documentation for x86 and NVIDIA Processors). This particular warning is listed but does not contain a detailed l explanation.

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.

-Mat

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.