Re: Allocatable arrays in derived types



"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


.



Relevant Pages

  • Re: Procedure Pointer (Components) with no explicit interface and with implicit typing
    ... in principle, I can assign to it either a function nor a subroutine, e.g. ... "7.4.2.2 Procedure pointer assignment" ... "If proc-pointer-object has an implicit interface and is explicitly ... external:: func, sub ...
    (comp.lang.fortran)
  • Re: Pointer-valued function to access inner components
    ... implicit none ... Return a F90 pointer which points to the diagonal of T. ... a copyin/copyout on array A during the procedure call. ... subroutine dirty_pointer_1d ...
    (comp.lang.fortran)
  • Re: Fortran based MEX w/ COMMON/SAVE
    ... I believe dat (pointer to the array) and the ... SAVE at the begining of each subroutine is a bit unusual to me. ... > to unload it if there isn't a Fortran END or STOP statement. ... interaction w/ Matlab). ...
    (comp.soft-sys.matlab)
  • background process to monitor cursor location
    ... Inside the Document_Opensubroutine, I am using the Timer and DoEvents ... text form fields used for data entry, then a pointer to that field is stored. ... My concern/question: ...
    (microsoft.public.word.vba.general)
  • Re: Copy-in/Copy-out
    ... -|declared as a target or pointer, it should be safe to assign a pointer ... -| Character, Intent:: str* ... -| End Interface ... -| Subroutine SubTarget! ...
    (comp.lang.fortran)