- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have encountered a problem, when trying to pass an array with the target attribute as an actual argument to a procedure with a pointer, intent(in) dummy argument via a generic interface. The minimal working example below demonstrates the problem. Calling subptr_int1 directly works, but via the `subptr` interface does not, the compiler complains about not being to able to find a matching interface for the call. Also, it seems, that for scalars it works with the interface. As far as I can judge, the code is standard conforming, two other compilers have no problems to compile it.
end program test_target_program
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
An array descriptor is not a pointer. Your subroutine requires a reference to a pointer be passed.
Note, should you flip the arguments about (call with pointer to subroutine with array), the actual argument is that which the pointer points to and not the pointer itself.
module test_target
implicit none
interface subptr
module procedure subptr_int1
end interface subptr
contains
subroutine subptr_int1(val)
integer, pointer, intent(in) :: val(:)
print *, "INTEGER1 PTR obtained", val(1)
end subroutine subptr_int1
end module test_target
program test_target_program
use test_target
implicit none
integer, target :: int1val(1)
integer, pointer :: p(:)
int1val(1) = 42
p => int1val
call subptr(p)
end program test_target_program
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The array in question (int1val) has the "target" attribute, therefore, according to the standard, it should be allowed to be an actual argument for a dummy argument with the 'pointer, intent(in)' argument. Consequently, the example above is correct and standard conforming.
Note, that if I directly call the routine with "call subptr_int1(int1val)", the code compiles and works as supposed without any further changes. It is only the generic interface, which confuses the Intel compiler. And, if I turn int1val and val into a scalar, the code again compiles and works without further changes. It is only the combination of using an array and the generic interface, where the compiler misbehaves.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm inclined to agree with @BalintAradi that the code should be accepted. Generic resolution isn't quite the same as argument association, but I think this cases passes the test. It's a fairly new thing in the language to allow passing a non-pointer to an INTENT(IN) pointer, and it's likely that the ifort developers overlooked adding a check for this in generic resolution.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
>>I'm inclined to agree with @BalintAradi that the code should be accepted.
I disagree for this reason:
The interface has been declared. In this specific example, then subroutine dummy argument for the pointer had intent(in) ...
However, consider if the intent were instead intent(inout)
In this case, had the call passed a pointer into the subroutine, the caller's pointer could be modified with => as well as have the pointer's target altered with =.
Orthogonality should not be broken dependent upon INTENT(IN) verses INTENT(INOUT) IMHO
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
For whatever it's worth, I too think the program conforms and that Intel Fortran compiler should process the code ok.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
@jimdempseyatthecove I think, if a module procedure can be called directly with a given actual argument, one should be also able to call it with the same actual argument via the generic interface, if it is listed in that generic interface. The direct call works if the pointer dummy argument of the called subroutine is intent(in), and it does not work, if the pointer dummy argument is intent(inout) (as dictated by the standard). I'd expect the call via the generic interface to behave the same way.
Also, as I mentioned above the posted example can be compiled and is working perfectly even with the Intel compiler if the dummy and the formal arguments are changed to scalars. So, I'd guess, the array case was just simply overseen.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Jim, the standard already carves out an exception for this case:
If the dummy argument does not have INTENT (IN), the actual argument shall be a pointer. Otherwise, the actual argument shall be a pointer or a valid target for the dummy pointer in a pointer assignment statement. If the actual argument is not a pointer, the dummy pointer becomes pointer associated with the actual argument. (15.5.2.7p2)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
If I read that correctly (correct me if I am wrong)...
"If the dummy argument does not have INTENT (IN), the actual argument shall be a pointer. " would apply to INTENT(OUT), INTENT(INOUT) and INTENT not specified.
The above is ambiguous (or maybe not). Is this a copy of the pointer of the caller or is this a reference to the caller's pointer?
My preference as to the decision made by the Fortran committee would be that this be a reference to the caller's pointer else how could you have a subroutine returning a pointer? Or, as an extension, a function returning a pointer?
Jim Dempsey
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, any INTENT not (IN), including unspecified, requires that the actual argument be a pointer if the dummy is a pointer. I don't think it is ambiguous.
Subroutines don't "return" anything, and I don't see the connection with functions returning pointers. This feature allows you to pass a non-pointer to a pointer under conditions that disallow changes to the pointer (INTENT(IN)). The dummy pointer becomes associated with the actual argument (rather than the target of a pointer actual argument).
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I filed a bug report, CMPLRIL0-34402, and referenced this discussion. Let's see what our Intel Fortran compiler developers have to say.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The fix will be available in the next oneAPI release.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page