Re: Allocatable arrays in derived types
- From: "James Van Buskirk" <not_valid@xxxxxxxxxxx>
- Date: Tue, 29 Apr 2008 14:30:21 -0600
"relaxmike" <michael.baudin@xxxxxxxxx> wrote in message
news:ec34d10a-0745-494c-9446-091ea4d950a9@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
extra_mem ()
{
struct array1_integer(kind=4) mydata;
static integer(kind=4) options.0[7] = {68, 255, 0, 0, 0, 1, 0};
mydata.data = 0B;
_gfortran_set_options (7, (void *) &options.0);
{
void * D.567;
mydata.dtype = 265;
mydata.dim[0].lbound = 1;
mydata.dim[0].ubound = 10;
mydata.dim[0].stride = 1;
[... with a "D.568 = __builtin_malloc (40);" and "D.567 = D.568;"]
mydata.data = D.567;
mydata.offset = -1;
[...]
We can see the dtype (data type ?), the lower bound 1, the upper
bound 10 (what is stride ? what is offset) and the memory location
is probably in mydata.data.
FX just a couple of days ago documented this:
http://groups.google.com/group/comp.lang.fortran/msg/a3c2275c13d8db90
The thing that makes me feel a little queasy is that gfortran
doesn't have the capability to express the stride in units
that aren't a multiple of the element size. What happens when
this is not the case?
C:\gfortran\clf\odd_str>type odd_str.f90
module odd_str
implicit none
contains
subroutine str1(x, p)
character(*), target :: x(:)
character(len(x)), pointer :: p(:)
p => x
write(*,*) x
end subroutine str1
subroutine set_ptr(x, p)
character(*), target :: x(:)
character(len(x(1:3))), pointer :: p(:)
call str1(x(:)(1:3), p)
end subroutine set_ptr
end module odd_str
program test
use ISO_C_BINDING, only: C_INTPTR_T
use odd_str
implicit none
! integer, parameter :: C_INTPTR_T = int_ptr_kind()
character(8), target :: x(8)
integer i
integer, parameter :: n = 3
type has_p3
character(n), pointer :: p(:)
end type has_p3
type(has_p3) h3
type has_p8
character(len(x)), pointer :: p(:)
end type has_p8
type(has_p8) h8
do i = 1,len(x)*size(x)
x((i+len(x)-1)/len(x))(modulo(i-1,len(x))+1:modulo(i-1,len(x))+1) &
= achar(32+i)
end do
write(*,*) x
! call str1(x(:)(1:n),h3%p)
call set_ptr(x,h3%p)
write(*,'(z16.16)') transfer(h3,[0_C_INTPTR_T])
write(*,*) h3%p
h8%p => x
write(*,'(z16.16)') transfer(h8,[0_C_INTPTR_T])
write(*,*) h8%p
end program test
C:\gfortran\clf\odd_str>gfortran odd_str.f90 -oodd_str
C:\gfortran\clf\odd_str>odd_str
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
!"#)*+1239:;ABCIJKQRSYZ[
00000000004A5A20
FFFFFFFFFFFFFFFF
00000000000000F1
0000000000000001
0000000000000001
0000000000000008
* #)*+1239:;ABCIJKQRSYZ[
000000000022FD90
FFFFFFFFFFFFFFFF
0000000000000231
0000000000000001
0000000000000001
0000000000000008
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
C:\gfortran\clf\odd_str>rem edit for compatibility with ifort 9.1
C:\gfortran\clf\odd_str>ifort odd_str.f90
Intel(R) Fortran Compiler for Intel(R) EM64T-based applications, Version 9.1
Build 20061104
Copyright (C) 1985-2006 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 8.00.40310.39
Copyright (C) Microsoft Corporation. All rights reserved.
-out:odd_str.exe
-subsystem:console
odd_str.obj
C:\gfortran\clf\odd_str>odd_str
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
!"#)*+1239:;ABCIJKQRSYZ[
0000000000471540
0000000000000003
FFFFFFFFFFFFFFF8
0000000000000001
0000000000000001
0000000000000000
0000000000000008
0000000000000008
0000000000000001
!"#)*+1239:;ABCIJKQRSYZ[
0000000000471540
0000000000000008
FFFFFFFFFFFFFFF8
0000000000000007
0000000000000001
0000000000000000
0000000000000008
0000000000000008
0000000000000001
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`
So it seems that gfortran is treating x(:)(1:3) as an expression in
subroutine set_ptr, so p ends up pointing at the expression which is
out of scope by the time control reaches program test again. In
N1601.pdf, section 6.1.1 it says:
"If the parent is a variable, the substring is also a variable."
And indeed ifort 9.1 seems to point at the original address. You
need the extra level of indirection to see this issue with gfortran
because when str1 was called directly in this example the string
didn't end up getting munged. Is gfortran correct to treat
x(:)(1:3) as a variable or does it need to express strides in
bytes rather than element storage units so that it could express
a pointer to it correctly?
--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end
.
- Follow-Ups:
- Re: Allocatable arrays in derived types
- From: paul . richard . thomas
- Re: Allocatable arrays in derived types
- References:
- Allocatable arrays in derived types
- From: Gib Bogle
- Re: Allocatable arrays in derived types
- From: Arjen Markus
- Re: Allocatable arrays in derived types
- From: relaxmike
- Re: Allocatable arrays in derived types
- From: Richard Maine
- Re: Allocatable arrays in derived types
- From: relaxmike
- Allocatable arrays in derived types
- Prev by Date: Re: Allocatable arrays in derived types
- Next by Date: Re: variable length of integer
- Previous by thread: Re: Allocatable arrays in derived types
- Next by thread: Re: Allocatable arrays in derived types
- Index(es):
Relevant Pages
|