Code Comments

Programming Forum and web based access to our favorite programming groups.
For Programmers: Free Programming Magazines | New: Database administration forum
Registration is free! Edit your profileCalendarFind other membersFrequently Asked QuestionsSearch -> 
Post New Thread











Thread
Author

Re: Reference to derived type element by index?
"Rob Crain" <r.a.crain@durham.ac.uk> wrote in message
news:fsokhs$kda$1@heffalump.dur.ac.uk...

> Since it's not mission critical and I'm pushed for time I opted for an
> inelegant select case statement; it does the job. Thanks to all for your
> responses though - when I get time to tune the code I'll revisit Dick's
> suggestion, it looks like it might be the answer.

Since C binding was introduced, you can point at any TARGET with
any kind of pointer you want, just like in C.

C:\gfortran\clf\fake_label>type fake_label.f90
module fake_label_mod
implicit none
private
integer, parameter :: circle_label_len = 20
public circle_datatype
type circle_datatype
real radius
real x
real y
real z
character(len=circle_label_len) circle_label
end type circle_datatype
end module fake_label_mod

program fake_label
use fake_label_mod
use ISO_C_BINDING
implicit none
type(circle_datatype), target :: circle1
real, pointer :: pcircle1(:)
integer i

call C_F_POINTER(C_LOC(circle1), pcircle1, [4])
pcircle1 = [(i,i=3,15,4)]
circle1%circle_label = "It's a circle"
write(*,*) circle1
end program fake_label

C:\gfortran\clf\fake_label>c:\gfortran\win64\bin\x86_64-pc-mingw32-gfortran
fake
_label.f90 -ofake_label

C:\gfortran\clf\fake_label>fake_label
3.0000000       7.0000000       11.000000       15.000000     It's a
circle


Thus in the above I have pointed at the four REAL elements of circle1
with a pointer to an array of REALs, and accessed them as an array
of REALs.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Report this thread to moderator Post Follow-up to this message
Old Post
James Van Buskirk
03-31-08 02:16 AM


Re: Reference to derived type element by index?
James Van Buskirk <not_valid@comcast.net> wrote:

> Since C binding was introduced, you can point at any TARGET with
> any kind of pointer you want, just like in C.

And just like in C, that doesn't actually mean it is standard conforming
or portable. It just means that the compiler isn't likely to XXXXX about
it; whether it works as intended is another matter entirely.

> Thus in the above I have pointed at the four REAL elements of circle1
> with a pointer to an array of REALs, and accessed them as an array
> of REALs.

Yep. Odds are even fairly good that it will work in most environments.
But it is *NOT* standard conforming. If you find an environment where it
fails, you'll have no recourse.

The standard doesn't specify that the components are stored in that way.
This isn't even a matter of having to read the whole standard and
concluding that one couldn't find such a specification. The standard
explicitly says that there is no such specification.

You might improve the odds by making the type a sequence type. Even
then, it isn't guaranteed because the type wouldn't be a numeric
sequence.

You might improve them even more by making it a bind(c) type. I don't
recall C's rules on this kind of thing.

--
Richard Maine                    | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle           |  -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard Maine
03-31-08 02:17 AM


Re: Reference to derived type element by index?
Richard Maine wrote:
> James Van Buskirk <not_valid@comcast.net> wrote:
 

> And just like in C, that doesn't actually mean it is standard conforming
> or portable. It just means that the compiler isn't likely to XXXXX about
> it; whether it works as intended is another matter entirely.
(snip)

> You might improve them even more by making it a bind(c) type. I don't
> recall C's rules on this kind of thing.

The one I remember is that a pointer to a struct is equal to a
pointer to the first element.  While padding is allowed, consecutive
elements of the same type should not need padding.  (I am not sure
that the standard says that, though.)   Note that any required
padding is always included in each element.  That is, the sizeof
a struct (or any type) includes any padding needed to make an array
out of that type.

The easy answer in C is to make it an array and #define the members:

struct c { double coord[3];};

#define x coord[0]
#define y coord[1]
#define z coord[2]

-- glen



Report this thread to moderator Post Follow-up to this message
Old Post
glen herrmannsfeldt
04-03-08 12:43 AM


Re: Reference to derived type element by index?
On 2 avr, 15:19, glen herrmannsfeldt <g...@ugcs.caltech.edu> wrote:
> Richard Maine wrote: 
>
> (snip)
> 
>
> The one I remember is that a pointer to a struct is equal to a
> pointer to the first element.  While padding is allowed, consecutive
> elements of the same type should not need padding.  (I am not sure
> that the standard says that, though.)   Note that any required
> padding is always included in each element.  That is, the sizeof
> a struct (or any type) includes any padding needed to make an array
> out of that type.
>
> The easy answer in C is to make it an array and #define the members:
>
> struct c { double coord[3];};
>
> #define x coord[0]
> #define y coord[1]
> #define z coord[2]
>
> -- glen

My proposal:

integer, parameter :: radius = 0
integer, parameter :: x = 1
integer, parameter :: y = 2
integer, parameter :: z = 3

type circle_datatype
real               :: f(0:3)
character(len=...) :: circle_label
endtype circle_datatype
type(circle_datatype) :: circle

circle%f(radius) = ...
circle%f(0) = ...

Depending on the frequency of access by index or by name, this
solution may be more interesting than a select case.

Report this thread to moderator Post Follow-up to this message
Old Post
sbergero@gcaon.com
04-03-08 12:43 AM


Re: Reference to derived type element by index?
On Mar 30, 7:30=A0am, Dick Hendrickson <dick.hendrick...@att.net> wrote:
> Rob Crain wrote: 
> 
> 
> 
>
> If you don't mind making the code clumsy, error-prone, and difficult
> to read, it's trivial ;).
>
> Create a hidden helper type, something like
> =A0 =A0 =A0type helper
> =A0 =A0 =A0 =A0 integer =A0:: =A0index
> =A0 =A0 =A0 =A0 real =A0 =A0 :: =A0x
> =A0 =A0 =A0 =A0 character(len=3Dwhatever) =A0:: =A0c
> =A0 =A0 =A0 =A0 ! any other types that are in circle_datatype
> =A0 =A0 =A0endtype helper
>
> Next create some generic operators or functions that return type
> helper results.
> =A0 =A0 =A0i .func. value
> or maybe
> =A0 =A0 =A0func(i,value)
> returns a type helper result with the index set to i, and the
> appropriate x or c set to value. =A0You'll, obviously, need one
> function for each type of element in circle_datatype. =A0The
> character one is trivial, the real one needs a select case.
>
> You can then also provide overloads to do arithmetic between
> type helper and the intrinsic types, helper types, and
> circle_datatype and return type helper.
>
> =A0 =A0 =A0 (i .func. circle) * 3.14 * (j .func. other_circle)**2
>
> Then create an assignment operator that assigns type helper to
> type circle by using an internal select case to assign to the
> INDEXth element.
>
> The result is that
> =A0 =A0 =A0 =A0circle =3D i .func. value
>
> is ultimately equivalent to
> =A0 =A0 =A0 =A0call assigner(circle, i, value)
>
> I'm not real happy with putting the circle subscript on the right,
> it's ugly and error-prone. =A0But I think it'll work.
>
> After thinking about this, why not just create a few generic
> subroutines that implement the above call if you only want to
> do assignments that update (but not use) elements?
>
> If you're not in a big hurry and can wait until 2008, the new
> Fortran allows pointer functions on the left hand side.
> You could probably make
> =A0 =A0 =A0 circle.element.i =3D whatever
> do what you want. =A0But that won't be standard until later this
> year. =A0It might take even longer to get a F2008 compiler :(.
>
> Dick Hendrickson

Isn't the solution I posted slightly better/easier than having to
define an operator?  Or maybe I'm missing something.

John.

Report this thread to moderator Post Follow-up to this message
Old Post
jwm
04-03-08 03:56 AM


Re: Reference to derived type element by index?

"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message
 news:HfadnRt3I9q_Rm7anZ2dnUVZ_oaonZ2d@co
mcast.com...
> Richard Maine wrote: 
> 
> 
> (snip)
> 
>
> The one I remember is that a pointer to a struct is equal to a
> pointer to the first element.  While padding is allowed, consecutive
> elements of the same type should not need padding.  (I am not sure
> that the standard says that, though.)   Note that any required
> padding is always included in each element.  That is, the sizeof
> a struct (or any type) includes any padding needed to make an array
> out of that type.
>
> The easy answer in C is to make it an array and #define the members:
>
> struct c { double coord[3];};
>
> #define x coord[0]
> #define y coord[1]
> #define z coord[2]

I've never seen this syntax before.  Is it standard c?  (Looks like it.)

--

"That this social order with its pauperism, famines, prisons, gallows,
armies, and wars is necessary to society; that still greater disaster
would ensue if this organization were destroyed; all this is said only
by those who profit by this organization, while those who suffer from it
- and they are ten times as numerous - think and say quite the contrary."

~~  Leo Tolstoy



Report this thread to moderator Post Follow-up to this message
Old Post
Gerry Ford
04-03-08 11:27 AM


Re: Reference to derived type element by index?
"Richard Maine" <nospam@see.signature> wrote in message
news:1iem5vx.9ffoff14uwzvqN%nospam@see.signature...

> You might improve them even more by making it a bind(c) type. I don't
> recall C's rules on this kind of thing.

Yes, and I thought of declaring the derived type as BIND(C) because
it's not C's rules so much as what C itself is supposed to
interoperate with that the companion processor is going to emulate.
Win32 API in 64-bit mode requires natural alignment of data
elements up to 128 bits wide, but a companion processor that is
targeting an older version of Windows isn't going to have the
same kind of alignment restrictions.

The reason I didn't do so in my example lay in section 15.2.1 of
N1601.pdf:

"... if the type is character, interoperability also requires that
the length parameter be omitted or be specified by an initialization
expression whose value is one."

and further in section 15.2.3:

"... the components of the Fortran derived type have types and type
parameters that are interoperable with the types of the
corresponding components of the struct type."

So I think it would create problems because the O.P. seemed to
indicate a preference for a character component with nonunit LEN
(although what was intended wasn't made precise) so he would have
had to have restructured to an array of character*1 which would
have had its own syntactic downside in the body of the code.

C:\gfortran\clf\bad_len>type bad_len.f90
module bad_len
implicit none
type, BIND(C) :: bad_type
character(4) bad
end type bad_type
end module bad_len

C:\gfortran\clf\bad_len>C:\gcc_equation\bin\x86_64-pc-mingw32-gfortran -Wall
-c
bad_len.f90
bad_len.f90:4.22:

character(4) bad
1
Warning: Component 'bad' in derived type 'bad_type' at (1) may not be C
interope
rable, even though derived type 'bad_type' is BIND(C)

Mmmm, just a warning though.  How bad is the above code?

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Report this thread to moderator Post Follow-up to this message
Old Post
James Van Buskirk
04-03-08 11:27 AM


Re: Reference to derived type element by index?
James Van Buskirk <not_valid@comcast.net> wrote:

> "Richard Maine" <nospam@see.signature> wrote in message
> news:1iem5vx.9ffoff14uwzvqN%nospam@see.signature...
> 
>
> Yes, and I thought of declaring the derived type as BIND(C)...
...
> The reason I didn't do so in my example lay in section 15.2.1 of
> N1601.pdf:
>
> "... if the type is character, interoperability also requires that
> the length parameter be omitted or be specified by an initialization
> expression whose value is one."

Yeah. That issue ocurred to me, but I decided that lead into a possibly
substantial diversion (as you have seen). I didn't think it worth going
down that path as it didn't seem likely to help the OP's question. After
all, mixing of character and numeric data in the derived type throws a
whole host of extra caveats into the mix such that generalization
becomes tricky at best.

> the O.P. seemed to
> indicate a preference for a character component with nonunit LEN
> (although what was intended wasn't made precise) so he would have
> had to have restructured to an array of character*1 which would
> have had its own syntactic downside in the body of the code.

I didn't read that into the OP's post. What I saw was a preference for a
form that isn't valid regardless of whether you use a character string
or an array of character (namely, that the length or size was
unspecified). That seemed like a matter orthogonal to the question
asked, so I didn't go into alternatives - just mentioned that it was
invalid.

The alternatives are...nontrivial.

Perhaps the closest in concept might be a parameterized derived type,
where objects of the type could have assumed type parameter values. But
that's an f2003 feature, and one of the last ones that vendors seem to
be implementing. I'm also not sure whether it actually fits the intended
use or not. It would sure kill the possibility of also being bind(c).

Making the string allocatable length would be another f2003 possibility,
depending on the intended use. And allocatable string length seems to be
another of the f2003 features that is being slow to get implemented *too
bad, as I'm quite find of the feature).

Making the string an allocatable size array of char would at least get
you down to f95+tr, but would still be incompatible with bind(c).

Making the string a pointer to an array of char is legit in plain old
f95, but again incompatible with bind(c), and it has all the usual
problems with using pointers as a hack to substitute for things like
allocatable.

> Mmmm, just a warning though.  How bad is the above code?

Well, it's nonstandard. I couldn't say what the odds of other compilers
accepting it would be. It is plausible that they might do the same thing
and accept it with a warning. But I couldn't guarantee that.

--
Richard Maine                    | Good judgement comes from experience;
email: last name at domain . net | experience comes from bad judgement.
domain: summertriangle           |  -- Mark Twain

Report this thread to moderator Post Follow-up to this message
Old Post
Richard Maine
04-03-08 11:27 AM


Re: Reference to derived type element by index?
"Richard Maine" <nospam@see.signature> wrote in message
news:1iesmwa.1s8zxrwcent9oN%nospam@see.signature...

> Making the string allocatable length would be another f2003 possibility,
> depending on the intended use. And allocatable string length seems to be
> another of the f2003 features that is being slow to get implemented *too
> bad, as I'm quite find of the feature).

You are not the only one.  Writing a getline() function would be a
snap with allocatable lengths, impossible with specification
expressions.  The allocatable lengths seem to be of the same
syntactic flavor as parameterized derived types, though, which is
probably why they get implemented so late.  Maybe I'm just dumb or
something, but parameterized derived types don't seem to me to add
all that much to the language for all the extra costs they impose
on the vendor and for all the stuff the user has to know to make
them a useful tool.

--
write(*,*) transfer((/17.392111325966148d0,6.5794487871554595D-85, &
6.0134700243160014d-154/),(/'x'/)); end



Report this thread to moderator Post Follow-up to this message
Old Post
James Van Buskirk
04-03-08 11:27 AM


Re: Reference to derived type element by index?

"James Van Buskirk" <not_valid@comcast.net> wrote in message
 news:lIqdnawoRKG6HmnanZ2dnUVZ_sudnZ2d@co
mcast.com...
> "Richard Maine" <nospam@see.signature> wrote in message
> news:1iesmwa.1s8zxrwcent9oN%nospam@see.signature...
> 
>
> You are not the only one.  Writing a getline() function would be a
> snap with allocatable lengths, impossible with specification
> expressions.  The allocatable lengths seem to be of the same
> syntactic flavor as parameterized derived types, though, which is
> probably why they get implemented so late.  Maybe I'm just dumb or
> something, but parameterized derived types don't seem to me to add
> all that much to the language for all the extra costs they impose
> on the vendor and for all the stuff the user has to know to make
> them a useful tool.
Dumb people rarely spell parametrized or the other one correctly.  I
couldn't say which is preferred.

--

"That this social order with its pauperism, famines, prisons, gallows,
armies, and wars is necessary to society; that still greater disaster
would ensue if this organization were destroyed; all this is said only
by those who profit by this organization, while those who suffer from it
- and they are ten times as numerous - think and say quite the contrary."

~~  Leo Tolstoy



Report this thread to moderator Post Follow-up to this message
Old Post
Gerry Ford
04-03-08 11:27 AM


Sponsored Links




Last Thread Next Thread Next
Pages (2): « 1 [2]
Search this forum -> 
Post New Thread

Fortran archive

Show a Printable Version Send to friend Email This Page to Someone! subscribe to this thread Receive updates to this thread
Computer Consultants
Programming Jobs
Visual Basic Controls
SQL Server Programming
Webservices
Java Security
Visual Studio
C# Programming
Visual J++
Software engineering
Open source Software
Perl Programming
PHP Programming
ASP Programming
ASP .NET Programming
Visual Basic Programming
Windows Scripting Host
Java Programming
Java Help
Java Beans
VBScript
Cobol
MAC Applications
Unix Programming
Forum Jump:
All times are GMT. The time now is 02:17 PM.

 
Free MCSE Braindumps | Real Estate Topics

Programming forum archive

Copyrights CodeComments.com 2004 - 2006

Powered by vBulletin Copyright 2000-2006 Jelsoft Enterprises Limited.