- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
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.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page