- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Having moved from fixed arrays that were equivalenced to dynamic arrays I'd like to reinstate an equivalent to the old equivalence.
[fortran]
program main
use iso_c_binding
implicit none
real(4) :: ra(0:11,3)
integer(4) :: ia(0:11,3)
common /x/ ra
equivalence(ra(0,1),ia(0,1))
real(4), allocatable :: wra(:,:)
integer(4), pointer :: wia_ptr(:,:)
ra = 0.0
ra(0,1) = transfer(1,0.0)
write(*,'(a,i0)') 'ia(0,1) = ',ia(0,1)
allocate(wra(0:11,3), source=0.0)
call c_f_pointer(c_loc(wra), wia_ptr, [12,3])
wra(0,1) = transfer(1,0.0)
write(*,'(a,i0)') 'wia_ptr(1,1) = ',wia_ptr(1,1)
end program main
[/fortran]
In order for my application to work I need wia_ptr(0,1) to be valid and == wra(0,1) but I can't work out the syntax. Is it possible using this method or is there another method that I should be using?
Thanks.
Link Copied
- « Previous
-
- 1
- 2
- Next »
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
jimdempseyatthecove wrote:
>>Fortran 2003 has ways of achieving the same outcome (putting values of objects of different types behind the same designator) that are generally superior, from the point of view of the language feature being a better fit to what the programmer actually wants to specify.
Then it should be relatively easy for you to convert the post #1 into (putting values of objects of different types behind the same designator) This isn't overtly clear when reading the F2003 spec.
Jim Dempsey
Well, if the specific code in post #1 is the basis, then it is easily replicated in much simpler manner in Quote #8.
As to what is possible with "putting values of objects of different types behind the same designator) that are generally superior, from the point of view of the language feature being a better fit to what the programmer actually wants to specify," I think there are tremendous possibilities with the latest Fortran standard:
module m implicit none private type, public :: any_t private class(*), allocatable :: m_dat contains private procedure, pass(this) :: set_t procedure, pass(this) :: get_i_t procedure, pass(this) :: get_r_t procedure, pass(this) :: get_c_t !.. procedure, pass(this), public :: ival => fget_i_t procedure, pass(this), public :: rval => fget_r_t procedure, pass(this), public :: cval => fget_c_t generic, public :: assignment(=) => set_t, get_i_t, get_r_t, get_c_t end type any_t contains subroutine set_t(this, newval) class(any_t), intent(inout) :: this class(*), intent(in) :: newval !.. select type ( newval ) type is ( integer ) allocate( this%m_dat, source = newval ) type is ( real) allocate( this%m_dat, source = newval ) type is ( character(len=*) ) allocate( this%m_dat, source = newval ) class default end select return end subroutine set_t subroutine get_i_t(ival, this) integer, intent(out) :: ival class(any_t), intent(in) :: this ival = this%ival() return end subroutine get_i_t subroutine get_r_t(rval, this) real, intent(out) :: rval class(any_t), intent(in) :: this rval = this%rval() return end subroutine get_r_t subroutine get_c_t(sval, this) character(len=:), allocatable, intent(out) :: sval class(any_t), intent(in) :: this sval = this%cval() return end subroutine get_c_t function fget_i_t(this) result(ival) class(any_t), intent(in) :: this !.. integer :: ival select type ( dat => this%m_dat ) type is ( integer ) ival = dat type is ( real ) ival = transfer(dat, mold=ival) type is ( character(len=*) ) ival = transfer(dat, mold=ival) class default end select return end function fget_i_t function fget_r_t(this) result(rval) class(any_t), intent(in) :: this !.. real :: rval select type ( dat => this%m_dat ) type is ( integer ) rval = transfer(dat, mold=rval) type is ( real ) rval = dat type is ( character(len=*) ) rval = transfer(dat, mold=rval) class default end select return end function fget_r_t function fget_c_t(this) result(sval) class(any_t), intent(in) :: this !.. character(len=:), allocatable :: sval select type ( dat => this%m_dat ) type is ( integer ) allocate( character(len=4) :: sval ) sval = transfer(dat, mold=sval) type is ( real ) allocate( character(len=4) :: sval ) sval = transfer(dat, mold=sval) type is ( character(len=*) ) sval = dat class default end select return end function fget_c_t end module m program p use m, only : any_t implicit none type(any_t) :: foo character(len=:), allocatable :: bar foo = 1 print *, " foo = ", foo%ival() bar = foo print *, " bar = ", transfer(bar, mold=0) foo = 2.0 print *, " foo = ", foo%rval() bar = foo print *, " bar = ", transfer(bar, mold=0.0) foo = "Hello World!" print *, " foo = ", foo%cval() bar = foo print *, " bar = ", bar stop end program p
Upon execution,
foo = 1 bar = 1 foo = 2.000000 bar = 2.000000 foo = Hello World! bar = Hello World! Press any key to continue . . .
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Ian, your program from post 20 works in the next major version, so it looks as if we fixed that one.
C:\Projects>ifort U541989.f90
Intel(R) Visual Fortran Intel(R) 64 Compiler XE for applications running on Intel(R) 64, Version Mainline Beta Build x
Built Feb 22 2015 23:51:01 by iclproj
Copyright (C) 1985-2015 Intel Corporation. All rights reserved.
Microsoft (R) Incremental Linker Version 10.00.40219.01
Copyright (C) Microsoft Corporation. All rights reserved.
-out:U541989.exe
-subsystem:console
U541989.obj
C:\Projects>U541989.exe
a(0,1) = 0
a(1,2) = 1.000000

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page
- « Previous
-
- 1
- 2
- Next »