Reputation: 1045
For interoperability with the C programming language I need to cast a pointer in Fortran. Essentially, I like to achieve in Fortran what looks the following in C:
#include <stdio.h>
int main(int argc, char **argv)
{
int n = 100;
long ptr;
ptr = (long) &n;
printf("ptr: %ld\n", ptr);
}
(long
used for simplicity here, int_ptr_t
should be preferred.) The example outputs:
ptr: 140737488349460
But trying the same in Fortran using transfer()
leads to something different:
program main
implicit none
integer, target :: n = 100
integer(kind=8) :: ptr
ptr = transfer(loc(n), ptr)
print '(a, i0)', 'ptr: ', ptr
end program main
Output:
ptr: 6296120
One could also use the appropriate ISO C binding types and functions, with the very same result:
program main
use, intrinsic :: iso_c_binding
implicit none
integer(kind=c_int), target :: n = 100
integer(kind=c_intptr_t) :: ptr
ptr = transfer(c_loc(n), ptr)
print '(a, i0)', 'ptr: ', ptr
end program main
Why is loc(n)
/c_loc(n)
not returning a similiar memory address?
(Examples have been compiled with GCC 9 and GNU Fortran 9.)
Upvotes: 0
Views: 1050
Reputation: 1045
Fortran only stores allocatable variables on the stack. Therefore, the variable of which the stack address is wanted must be declared as pointer or allocatable:
program main
use, intrinsic :: iso_c_binding
implicit none
integer(kind=c_int), pointer :: n => null()
integer(kind=c_intptr_t) :: ptr
allocate (n)
n = 100
ptr = transfer(c_loc(n), ptr)
print '(a, i0)', 'ptr: ', ptr
end program main
Result:
ptr: 34366292000
Upvotes: 1