- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hello, I posted a small program the other day on Fortran Discourse to illustrate how to use pointer function to implement a simple dictionary. PierU followed up on my suggestion that this can be made more flexible by putting everything in a type with type-bound procedures. The resulting code is:
module container_m
implicit none
type container_t
real, pointer :: a(:)
contains
procedure :: v
end type
contains
function v(this,i)
class(container_t), target, intent(inout) :: this
integer, intent(in) :: i
real, pointer :: v
v => this%a(i)
end function
function w(this,i)
type(container_t), target :: this
integer, intent(in) :: i
real, pointer :: w
w => this%a(i)
end function
end module
program container
use container_m
implicit none
type(container_t), target :: x
integer :: i
do i = 1, 10, 2
x%v(i) = i
end do
do i = 2, 10, 2
w(x,i) = i
end do
do i = 1, 10
print*, i, ' : ', x%v(i), w(x,i)
end do
endgfortran is happy to compile this program but ifx (I am using 2025.0.0 at the moment) is not:
ifx chk_p.f90 -standard-semantics
Intel(R) Fortran Compiler for applications running on Intel(R) 64, Version 2025.0.0 Build 20241008
Copyright (C) 1985-2024 Intel Corporation. All rights reserved.
chk_p.f90(38): error #6515: This function, which is specified as the left side of an assignment statement, is invalid. [V]
x%v(i) = i
----------^
compilation aborted for chk_p.f90 (code 1)So the question now is: is this legal or not? And if it is not legal, what is the rationale?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
has to be a bug. The workaround does not fail but in reality that should make no difference, the fact that it does the opposite is a bug one way or the other.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have not a clue what the intended outcome of this program is meant to be, I just can't see how a function call can be on the LHS of an assignment. I am interested so see how this thread develops as there may be a hole in my understanding which may lead to an existential crisis! Just for the record could you take me through what the intended outcome should be of x%v(i) = i please.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The (plain) feature is described in MFE (version for 2023), paragraph 8.7 and figure 8.5. The output from the program built with gfortran is:
1 : 1.00000000 1.00000000
2 : 2.00000000 2.00000000
3 : 3.00000000 3.00000000
4 : 4.00000000 4.00000000
5 : 5.00000000 5.00000000
6 : 6.00000000 6.00000000
7 : 7.00000000 7.00000000
8 : 8.00000000 8.00000000
9 : 9.00000000 9.00000000
10 : 10.0000000 10.0000000You see two ways of getting a pointer to an element of the array x%a. The feature "simply" allows the pointer result of a function to be used on the left-hand side of an assignment. So, the first loop uses a type-bound procedure to set the odd-numbered elements and the second loop uses a "loose" function to set the even-numbered elements.
If I leave out the first loop (so x%v(i) = ...) then ifx accepts the program.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
OK thanks I get what your are trying to do, but it seems counter intuitive to how a function assignment would work in the rest of the Fortran universe. You are effectively saying x=y and defining what x actual is at the same time. I will be interested to see authoratative responses, I hope there are some.
.... But it seems " Fortran standard (since F08) supports referencing a function which returns a pointer in variable-definition contexts"
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I tested several things:
- With gfortran (14.2.0)
The compilation is OK, but there is a segmentation fault at run time: "invalid memory reference"
I think you need to allocate "a" first in the program with, for example:
allocate (x%a(10))
Then, the code provides the results you are showing.
- With IFX 2025.3.0
With your code, I get the same compilation error as you (error #6515 ...)
Leaving out the first loop, the compilation is OK.
But at run time, there is an access violation at the first assignment "w(x,i) = i"
After allocating "a" as with gfortran, the result is as follows (which I think is what we are expecting):
1 : 0.000
2 : 2.000
3 : 0.000
4 : 4.000
...
So I think there is definitely a problem with IFX when it comes to the assignments involving x%v(i) = i, but I think that you must allocate "a" in all cases.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You're right about that. I apparently did not correct some of the variations I tried. The original code by PierU had a non-allocatable array of 10 elements. I experimented with a array pointer, assuming that might solve it, but that was not the case. Since the "w" version does work, I do believe ifx is in error.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The solution with IFX is to modify the function "v" as follows:
function v(this,i) result(res)
class(container_t), target, intent(inout) :: this
integer, intent(in) :: i
real, pointer :: res
res => this%a(i)
end functionThe key element seems to be distinguishing the function name from the value returned by that function.
After this modification, the code compiles and runs as expected with IFX.
However, I don't fully understand why this modification is not necessary for the 'w' function. Maybe because it is not a procedure of the container_t type ...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Oh, thanks a lot for this workaround, This does show it is an error in the compiler, as there should be no need for defining a separate name for the return value. But I will pass this on.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I think the code is legal, following the rules down to R1522 in the Fortran 2023 Interpretation document:
R1033 (10.2.1.1) defines assignment-stmt is variable = expr
In R902 (9.2) variable can be a function-reference
In R1520 (15.5.1) function-reference is a procedure-designator with its argument list
In R1522 (15.5.1) procedure-designator can be data-ref % binding-name (i.e. a TBP call)
I can't see anything in the constraints here disallowing a TBP from use as an accessor function.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, we all agree that the code is legal, I think this is not the issue.
But IFX triggers a compilation error with the initial version of the code. The workaround is to use different names for the function and the returned value. Unsure whether this is a bug or not...
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, I think your post hadn't appeared when I was writing my reply to the OP. That's a good workaround, I normally put a result clause on any functions I write.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
has to be a bug. The workaround does not fail but in reality that should make no difference, the fact that it does the opposite is a bug one way or the other.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page