Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29389 Discussions

Pointer function as type-bound procedure - valid?

Arjen_Markus
Honored Contributor II
780 Views

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

end

gfortran 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?

 

 

0 Kudos
1 Solution
andrew_4619
Honored Contributor III
541 Views

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.

 

View solution in original post

0 Kudos
11 Replies
andrew_4619
Honored Contributor III
772 Views

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.

0 Kudos
Arjen_Markus
Honored Contributor II
745 Views

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.0000000

You 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.

0 Kudos
andrew_4619
Honored Contributor III
729 Views

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"

 

0 Kudos
MarcGrodent
New Contributor II
704 Views

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.

 

 

0 Kudos
Arjen_Markus
Honored Contributor II
697 Views

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.

0 Kudos
MarcGrodent
New Contributor II
612 Views

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 function

The 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 ...

0 Kudos
Arjen_Markus
Honored Contributor II
604 Views

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. 

0 Kudos
Mark_Lewy
Valued Contributor I
592 Views

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.

 

0 Kudos
MarcGrodent
New Contributor II
587 Views

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...

0 Kudos
Mark_Lewy
Valued Contributor I
580 Views

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.

0 Kudos
andrew_4619
Honored Contributor III
542 Views

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.

 

0 Kudos
Reply