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

Fortran Discourse Issue

JohnNichols
Valued Contributor III
1,638 Views
module foo

contains

    subroutine foobar1(a)
    integer, intent(inout), target :: a(:)
    integer, pointer :: P(:)
    integer f,g,h,j
    a(:) = 1
    call foobar2(size(a),a,P)
    f = P(1)
    print*, P(1), P(2),f  ! unreasonnable expectation: 1  2
    a(:) = [1,2]
    print*, P   ! unreasonnable expectation: 1  2
    end subroutine

    subroutine foobar2(n,a,P)
    integer, intent(in) :: n
    integer, intent(in), target :: a(n)
    integer,  intent(inout), pointer :: P(:)
    P => a
    
    print*, P   ! unreasonnable expectation: 1  2
    end subroutine

end module

program test
use foo

    integer :: a(4)
    write(*,*)"Here"
    call foobar1( a(::2) )

end

There is a discussion on a variant to this program on Fortran Discourse. The issue appears to be that the print statement at Line 12 is destroying the pointer, at line 11 upon return in IFX P is ok in the debug window. Pictures show the problem, this appears to be a bug in Print.  As the second print returns P1 as a set distance from the first print. 

 

Screenshot 2025-09-21 120318.png

Screenshot 2025-09-21 120329.png

0 Kudos
6 Replies
JohnNichols
Valued Contributor III
1,632 Views

To see P in debug it had to be uppercase. 

Metcalf and Eddy Fortran Explained notes that only uppercase letters need to be supported by a compiler.  

+ Problems 3.14 in their book talk about equations and precedence. 

 

program test
use foo

    integer :: a(4), b,c,d,e
    write(*,*)"Here"
    call foobar1( a(::2) )
    
    b = 6
    c = 4
    d = 2
    
    e = b/c/d
    write(*,*)e

end

e gives the Metcalf answer zero.  It is actually 0.75 if real. 

0 Kudos
JohnNichols
Valued Contributor III
1,140 Views

Actually there is a deeper issue here.  The original author does not initialize p to a  in foo bar 1, but passes them then associates, and then returns. 

P once returned exists holds the [1,1] value but it not associated, as soon as you go into print P just picks up crap. 

The print statement should not allow unassociated pointers to be printed. 

It works as required if p=> a in foobar 1

0 Kudos
jimdempseyatthecove
Honored Contributor III
818 Views

foobar2 has P declared as intent(inout) .AND. associates P=>a (slice of caller's a). Therefor, P should have been associated in the caller (iow P=>a should redeclare the pointer within the caller to foobar2 (foobar1) as well as locally within foobar2)

What happens when foobar2 declares P with intent(out)?

 

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
498 Views

Jim:

I read about this on Fortran discourse and as usual just had a play.  Then I noticed that P lasted until the print, but I could do a loop with add P(1) to f and then print again and get 1, 2, 3 etc. 

P(1) remains 1 after the print always.  It does not destroy it, but to print it you need to assign it to an integer say f  then Print* f works.  

In LISP we would call it a side affect, here undocumented, so to me it just normal LISP form, but in Fortran it is bad programming from the scratch. 

P should be set as null when defined, if you are going to pass two elements from A make them a two element vector V P=> V and then pass P and V to foobar 2. 

Achieve same thing but better documented.  Then set A with the new V on return. 

Fortran discourse get caught up in esoteric arguments about Fortran innards, it is fun to look at, but discussing it is always a challenge as I look at the whole issue and they get caught up on the minor points.   I think this is your request. Note output. 

module foo

contains

    subroutine foobar1(a)
    integer, intent(inout), target :: a(:)
    integer, pointer :: P(:)
    integer f,g,h,j
    a(:) = 1
    f = 0
    call foobar2(size(a),a,P)
    do i = 1,1000
    f = P(1) + f
    print*, f,p(1),a  ! unreasonnable expectation: 1  2
    a(:) = [1,i]
    end do
    end subroutine

    subroutine foobar2(n,a,P)
    integer, intent(in) :: n
    integer, intent(inout), target :: a(n)
    integer,  intent(out), pointer :: P(:)
    p => a
    a(:) = [1,2]
    print*, P   ! unreasonnable expectation: 1  2
    end subroutine

end module

program test
use foo

    integer :: a(4), b,c,d,e
    write(*,*)"Here"
    a = 1
    call foobar1( a(::2) )
    
  

end

 

Screenshot 2025-09-24 183059.png

 

0 Kudos
jimdempseyatthecove
Honored Contributor III
323 Views

In program test

call foobar1( a(::2) )

request a stride 2 section of the array be passed to foobar1

The interface for foobar1 declares the dummy argument (a) for actual argument a(::2) as a contiguous array.

Therefor, just prior to the call to foobar1 a copy of a(::2) is made to a temporary array and the reference to this is passed.

And following the call, the copy is written back into a(::2).

 

foobar2 associates the point P to a (which is the temporary created just prior to the call to foobar1 in the main program

This (should) point to a, the first entry does.

In foobar1, you only reference P(1). Maybe the compiler thinks anything after that is fair game.

Try changing:

print*, f,p(1),a

to

print*, f,p(1:2),a

 

Regardless of this works, I think this is a bug.

 

Jim Dempsey

0 Kudos
JohnNichols
Valued Contributor III
264 Views

No, it does not wark.

Wark = the OLD ENGLISH WORD for work.   

If I have a routine A and in A I pass the array AB out to a routine B and in B I create as a passed argument, which is a lousy idea, part of AB call it A  and a Pointer P passed to B but not assigned and in B I assign the partial pass A say to P and then return P, P should point to the partial pass.  

Why should it be processor dependent - the standard is not good. 

 

 

Here is the relevant stuff that started this exchange, not in proper order. 

Screenshot 2025-09-25 121514.png

Screenshot 2025-09-25 121721.png

 

Screenshot 2025-09-25 121514.pngScreenshot 2025-09-25 121612.pngScreenshot 2025-09-25 121721.pngScreenshot 2025-09-25 121811.png

0 Kudos
Reply