For Programmers: Free Programming Magazines  


Home > Archive > Fortran > February 2008 > printing a pointer in fortran









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author printing a pointer in fortran
Gerry Ford

2008-02-24, 4:45 am

I've looked around a little bit and have a critical mass of difficulties to
profitably ask for help.

Apparently, there is a pointer datatype in fortran. Through use of the
arrow operator one points to T1 with
p1 -> t1
Do I have the arrow operator correct here? It looks like it could just as
well be =>.

I don't feel like I can test this properly because if I write
write (*, *) p1
, I would get t1 in fortran.

In order for me to figure out whether I had the right thing, I would have to
pass the argument to c and use the p character conversion to see the darn
thing in printf. How do you know that you've referenced something properly
in fortran if you can't see the address in a print statement?

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Steven G. Kargl

2008-02-24, 4:45 am

In article <1203830368_33702@news.newsgroups.com>,
"Gerry Ford" <invalid@invalid.net> writes:
>
> In order for me to figure out whether I had the right thing, I would have to
> pass the argument to c and use the p character conversion to see the darn
> thing in printf. How do you know that you've referenced something properly
> in fortran if you can't see the address in a print statement?


You need to get Metcalf et al. Then you need to read and
understand its content. A fortran pointer isn't a C pointer.

--
Steve
Gerry Ford

2008-02-24, 4:45 am


"Steven G. Kargl" <kargl@troutmask.apl.washington.edu> wrote in message
news:fpr17a$73g$1@gnus01.u.washington.edu...
> In article <1203830368_33702@news.newsgroups.com>,
> "Gerry Ford" <invalid@invalid.net> writes:
>
> You need to get Metcalf et al. Then you need to read and
> understand its content. A fortran pointer isn't a C pointer.
>
> --
> Steve
>


I'm not MRC ignorant. In particular I believe that I would recall:
> understand its content. A fortran pointer isn't a C pointer.

, had this appeared there.

If Cohen and Maine didn't have a way of referencing each other, j3 would be
j two and a half with change. I am well aware that the chapet on iso c
binding was consciously avoided, like the unix chapter in K&R2.

As to facts, I offer my latest version of hello world in fortran:

program hello2
IMPLICIT NONE
integer, dimension(52) :: cards
integer counter, iterations
counter = 0
call random_seed()
do iterations = 1, 10000
call shuffle(cards)
call deal(cards, counter)
end do
!WRITE(*,*) cards
write(*,'(a)')"hello2"
write(*,'(a)')"26/17=1.52941176"
write(*,'(a,i5)') "iterations= ", iterations -1
write (*,'(a,i5)') "final counter= ", counter
contains
subroutine shuffle(cards)
integer :: cards(:), ii, index
real :: numbers(size(cards))
call random_number(numbers)
do ii = 1, size(cards)
index = minloc(numbers, dim=1)
cards(ii) = index
numbers(index) = 2.0
end do
end subroutine shuffle
subroutine deal(cards, counter)
integer :: cards(:), i, counter
do i = 1, 52, 2
if (modulo(cards(i), 13).eq.modulo(cards(i+1), 13)) then
!write (*,'(a,i5,i5,i5 )') "pair",i,cards(i),cards(i+1)
counter = counter + 1
end if
end do
end subroutine deal
end program

! gfortran2 hello2.f95 -o test2 >text55.txt 2>text56.txt

I hope to good God that pointers are different in fortran than c! Maybe, we
can shut up about them eventually.

cordially,


Steve Lionel

2008-02-24, 4:45 am

On Feb 24, 12:27 am, "Gerry Ford" <inva...@invalid.net> wrote:

> In order for me to figure out whether I had the right thing, I would have to
> pass the argument to c and use the p character conversion to see the darn
> thing in printf. How do you know that you've referenced something properly
> in fortran if you can't see the address in a print statement?


In Fortran, unlike C, when you use a pointer in a context that does
not explicitly require a pointer, it is automatically dereferenced.
You would use the ASSOCIATED intrinsic to see if a pointer is pointing
to the desired target.

Getting access to the actual address (and a Fortran pointer may have
more than an address, especially if it is pointing to an array) is not
simple. One way is to use C_LOC of the pointer to get a value of type
C_PTR and then use TRANSFER to convert it to an INTEGER of kind
C_INTPTR_T.

Steve
Gerry Ford

2008-02-25, 7:17 pm


"Steve Lionel" <steve.lionel@intel.com> wrote in message
news:1e3faea9-b79b-45f4-8edd-6db8cc8cb937@b29g2000hsa.googlegroups.com...
> On Feb 24, 12:27 am, "Gerry Ford" <inva...@invalid.net> wrote:
>
>
> In Fortran, unlike C, when you use a pointer in a context that does
> not explicitly require a pointer, it is automatically dereferenced.
> You would use the ASSOCIATED intrinsic to see if a pointer is pointing
> to the desired target.
>
> Getting access to the actual address (and a Fortran pointer may have
> more than an address, especially if it is pointing to an array) is not
> simple. One way is to use C_LOC of the pointer to get a value of type
> C_PTR and then use TRANSFER to convert it to an INTEGER of kind
> C_INTPTR_T.
>
> Steve


I'll look up 'associated' in my current reference, whence comes the
following:

PROGRAM Vector5

! enable IMPLICIT

real pointer :: p1
real, target :: t1

p1=>t1

t1 = 42

write (*,*) p1, t1

END

! gfortran2 -o vec vector5.f95
Gfortran won't have this p1 associated so with t1. I've relaxed everything
I can with types. I believe the equals sign to be the front half of the
arrow operator. Grateful for any tips.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Steve Lionel

2008-02-25, 7:17 pm

On Feb 25, 4:24 pm, "Gerry Ford" <inva...@invalid.net> wrote:

> Gfortran won't have this p1 associated so with t1. I've relaxed everything
> I can with types. I believe the equals sign to be the front half of the
> arrow operator. Grateful for any tips.


You're missing a comma between "real" and "pointer" in the declaration
of p1. Put that in and it works fine in ifort.

Steve
Steven G. Kargl

2008-02-25, 7:17 pm

In article <1203974148_40362@news.newsgroups.com>,
"Gerry Ford" <invalid@invalid.net> writes:

> I'll look up 'associated' in my current reference, whence comes the
> following:
>
> PROGRAM Vector5
>
> ! enable IMPLICIT
>
> real pointer :: p1
> real, target :: t1
>
> p1=>t1
>
> t1 = 42
>
> write (*,*) p1, t1
>
> END
>
> ! gfortran2 -o vec vector5.f95
> Gfortran won't have this p1 associated so with t1. I've relaxed everything
> I can with types. I believe the equals sign to be the front half of the
> arrow operator. Grateful for any tips.


If you fix the missing comma in the declaration of p1, you'll
get
mobile:kargl[207] gfc -o z j.f90
mobile:kargl[208] ./z
42.00000 42.00000

Here's a small variation of your program.

PROGRAM Vector5
integer(8) addr1, addr2
real, pointer :: p1
real, target :: t1
p1=>t1
t1 = 42
write (*,*) p1, t1
addr1 = loc(p1)
addr2 = loc(t1)
write (*,*) addr1, addr2
END

--
Steve
Gerry Ford

2008-02-25, 7:17 pm


"Steven G. Kargl" <kargl@troutmask.apl.washington.edu> wrote in message
news:fpvdb9$12p$1@gnus01.u.washington.edu...
> In article <1203974148_40362@news.newsgroups.com>,
> "Gerry Ford" <invalid@invalid.net> writes:
>
>
> If you fix the missing comma in the declaration of p1, you'll
> get
> mobile:kargl[207] gfc -o z j.f90
> mobile:kargl[208] ./z
> 42.00000 42.00000
>
> Here's a small variation of your program.
>
> PROGRAM Vector5
> integer(8) addr1, addr2
> real, pointer :: p1
> real, target :: t1
> p1=>t1
> t1 = 42
> write (*,*) p1, t1
> addr1 = loc(p1)
> addr2 = loc(t1)
> write (*,*) addr1, addr2
> END
>
> --
> Steve

I'm getting output, steve. dankenstein.
42.000000 42.000000
2293516 2293516

My current reference is _Programming in fortran 90_ by I. M. Smith, wherein
I see that I *did* blow the comma that steve mentions. Is it possible that
both responders are named steve?

The upthread code tests for the existence of a pair, I believe, as hole
cards. I have no idea what 1.53 says to this. 26/17 was the number that
Carl Goldman talked about as correct. I'd trust it.

Thanks again.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Gerry Ford

2008-02-26, 4:49 am


"Steve Lionel" <steve.lionel@intel.com> wrote in message
news:89580b35-0df4-4dd3-bbff-98ee88814471@e25g2000prg.googlegroups.com...
> On Feb 25, 4:24 pm, "Gerry Ford" <inva...@invalid.net> wrote:
>
>
> You're missing a comma between "real" and "pointer" in the declaration
> of p1. Put that in and it works fine in ifort.
>
> Steve


PROGRAM Vector6
implicit none
! add function from c
!! like this real(kind=8), external :: sqrt_from_c
!!! maybe real(kind=8), external :: ptr_prt_c

real, pointer :: p1, p2
real, target :: t1, t2
! real(kind=8), external :: ptr_prt_c

p1=>t1
p2=>t2

t1 = 42
t2 = 43.56

p2 => t1

write (*,*) p1, loc(t1)
write (*,*) p2


END

! gfortran2 -o vec vector6.f95
!! revise goocher


// p.c
#include <stdio.h>
void print_it(int *p)
{
printf("The pointer points to %p, which contains the value %d.\n",
(void *)p, *p);
}
// gcc -c p.c

Somehow, I've got all the ingredients here but can't stitch this together.


--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Steve Lionel

2008-02-26, 7:23 pm

On Feb 26, 3:57 am, "Gerry Ford" <inva...@invalid.net> wrote:

> Somehow, I've got all the ingredients here but can't stitch this together.


Does this help?

PROGRAM Vector6
use iso_c_binding
implicit none

real, pointer :: p1, p2
real, target :: t1, t2


p1=>t1
p2=>t2

t1 = 42
t2 = 43.56

p2 => t1

write (*,*) p1, loc(t1)
write (*,*) p2
write (*,*) "p2 points to t1?", associated(p2,t1)
write (*,*) "Address of what p2 points to", transfer(c_loc(p2),
0_C_INTPTR_T)

END

Compiled and run with ifort:

42.00000 1244912
42.00000
p2 points to t1? T
Address of what p2 points to 1244912

Steve
glen herrmannsfeldt

2008-02-26, 7:23 pm

Steve Lionel wrote:

(snip)

> write (*,*) "Address of what p2 points to", transfer(c_loc(p2),
> 0_C_INTPTR_T)


What does it do if you print the value of c_loc directly:

write (*,*) "Address of what p2 points to", c_loc(p2)

the compilers I have don't implement c_loc yet.

-- glen

Steve Lionel

2008-02-26, 7:23 pm

On Feb 26, 2:59 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:

> What does it do if you print the value of c_loc directly:
>
> write (*,*) "Address of what p2 points to", c_loc(p2)


C_LOC returns a value of type C_PTR which is a derived type with
private components. You can't print it directly. This is why I
"cheat" with TRANSFER. The standard specifies that C_PTR is
interoperable with a C pointer type.

Steve
Gerry Ford

2008-02-27, 5:13 am


"Steve Lionel" <steve.lionel@intel.com> wrote in message
news:0ddcc461-a921-4b72-9a95-cb01b362a9bb@t66g2000hsf.googlegroups.com...
> On Feb 26, 2:59 pm, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
>
>
> C_LOC returns a value of type C_PTR which is a derived type with
> private components. You can't print it directly. This is why I
> "cheat" with TRANSFER. The standard specifies that C_PTR is
> interoperable with a C pointer type.
>
> Steve
>

I got a lot farther with this stuff when I put that comma where it needs to
be. While I usually work within silverfrost, which has
wonderfully-informative error messages, I find that gfortran's remind me
more of perl or c. The sheer tonnage of error messages I have distributed
among the syntaxes could stun a team of oxen.

PROGRAM Vector_Sqrt

IMPLICIT NONE
!add function from c++
!real(kind=8), external :: dot_product_from_cplusplus

INTEGER, PARAMETER :: dp = KIND(0.0d0)

REAL(DP) :: vec_a(4), vec_b(4)
REAL, POINTER :: pa, pb
INTEGER :: i
integer(8) addr1, addr2
INTEGER a, b, c, total


DO i = 1, 4
vec_a(i) = SQRT(REAL(i, DP))
vec_b(i) = (-1.0_DP)*(i**2)
ENDDO

!pa=>vec_a
!pb=>vec_b

! WRITE(*,'(4F19.13)') vec_a, vec_b
addr1 = loc(vec_a)
addr2 = loc(vec_b)
write (*,*) addr1, addr2


END


! gfortran2 -c vector7.f95
! gfortran2 p.o vector7.o
! gfortran2 -o vec vector7.f95

So the idea is that I'm gonna send these addresses to an external c++
function to calculate the dot_product. My guess is that passing vector
length will help the process along, but ultimately, if you send the address
of two four vectors, what else is c++ gonna think, in particular when they
butt up in memory. Gfortran has the fourth value of vec_b immmediately
before the first value of vec_a.

I wonder how using the iso c binding is relevant to this. MR&C was
tragically lost and the only ones I saw at UNM were older versions, which
are gonna be horseshit on things that hadn't hapended yet. My other
reference has nothing on this.

I'll snip the source you posted last night for homework. Thanks.

--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Gerry Ford

2008-02-27, 5:13 am


"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
news:4LydnQLNJaTs81nanZ2dnUVZ_oqhnZ2d@co
mcast.com...
> Steve Lionel wrote:
>
> (snip)
>
>
> What does it do if you print the value of c_loc directly:
>
> write (*,*) "Address of what p2 points to", c_loc(p2)
>
> the compilers I have don't implement c_loc yet.

4.3.0 gfortran can do it:
PROGRAM Vector9
use iso_c_binding
implicit none

real, pointer :: p1, p2
real, target :: t1, t2


p1=>t1
p2=>t2

t1 = 42
t2 = 43.56

p2 => t1

write (*,*) p1, loc(t1)
write (*,*) p2
write (*,*) "p2 points to t1?", associated(p2,t1)
write (*,*) "Address of what p2 points to", &
& transfer(c_loc(p2),0_C_INTPTR_T)
write (*,*) "Address of what p2 points to", c_loc(p2)


END

! gfortran2 -o vec vector9.f95 2>text55.txt >text56.txt



42.000000 2293532
42.000000
p2 points to t1? T
Address of what p2 points to 2293532
Address of what p2 points to 2293532

Silverfrost wouldn't even hear of an iso c binding. I was surprised that it
issued an error.


--
Gerry Ford

"Er hat sich georgiert." Der Spiegel, 2008, sich auf Chimpy Eins komma null
beziehend.


Steve Lionel

2008-02-27, 8:18 am

On Feb 27, 12:06 am, "Gerry Ford" <inva...@invalid.net> wrote:

> So the idea is that I'm gonna send these addresses to an external c++
> function to calculate the dot_product. My guess is that passing vector
> length will help the process along, but ultimately, if you send the address
> of two four vectors, what else is c++ gonna think, in particular when they
> butt up in memory. Gfortran has the fourth value of vec_b immmediately
> before the first value of vec_a.


You are making much more work for yourself than required. Just pass
the "pointer" as an ordinary argument as you would to a Fortran
routine. Without an explicit interface saying that the corresponding
dummy argument is a POINTER or is assumed-shape, Fortran will simply
pass the address of the target and C++ can pick it up as float[] or
whatever. Just keep in mind that C/C++ uses zero-origin for indexing.

In the absence of BIND(C), you'll possibly need to use compiler
extensions, or at least knowledge of naming conventions, to make the
call to the C++ routine.

As for Silverfrost not recognizing ISO_C_BINDING, with the syntax used
in my example, it just looks like a module that happens to be
missing. If I had written instead:

USE, INTRINSIC :: ISO_C_BINDING

then Silverfrost would have gotten more .

Is there some reason to go to C++ to do a dot product?

Steve
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com