For Programmers: Free Programming Magazines  


Home > Archive > Fortran > September 2006 > Fortran pointers









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author Fortran pointers
Mathemagician

2006-09-19, 7:02 pm

Hi,

I have the following definition for a pointer to a 2-dimensional real
matrix

type real_matrix_pointer
real, dimension (:,:), pointer :: p
end type real_matrix_pointer

and the following data of that type

type (real_matrix_pointer) :: plotdata(0:3)

Then, in a subroutine I have the variable

real, dimension(:,:), pointer :: dat

and the pointer assignment

dat => plotdata(1)%p


Isn't the variable "dat" supposed to point to the same entity as
plotdata(1)%p ?

However, when I write out the first elements of "plotdata(1)%p" and
"dat"

write (6,*) plotdata(1)%p(1,1:20)
write (6,*) dat(1,1:20)

I get different values.

The first, plotdata(1)%p(1,1:20), has the correct values: an increasing
set of numbers 0.00, 0.37, 0.74, 1.11, ...
But the values displayed for dat are other numbers, which do appear in
the original plotdata(1)%p overall, but not at the same indices. The
values 0.00, 0.37, 0.74, 1.11 appear too, but at different locations.

What is the assignment

dat => plotdata(1)%p

supposed to do ? Point at the exact same entity as the original, I
would except.
Or is this compiler dependent ? I'm using the FTN95 compiler v.4.6.0.0
by Salford Software.

Thank you
Rainer

Richard E Maine

2006-09-19, 7:02 pm

Mathemagician <mathemagician@gmx.net> wrote:
[code snippet elided]

> dat => plotdata(1)%p
>
> Isn't the variable "dat" supposed to point to the same entity as
> plotdata(1)%p ?


Yes. I can't tell from what you posted whether there is some error
elsewhere in the code that is causing the reported symptoms or whether
you have a compiler bug. It is *very* (note the emphasis) easy to make
errors with pointer stuff - and even more so if you aren't completely
sure of how they work (your guesses look correct for what that is
worth). For example, the simple typo of typing = instead of => gives a
completely different meaning. Thus my first suspicion would be that
there is something wrong with the code. But I don't see anything wrong
with what you posted. This means either

1. I didn't see it (that can happen, of course).

2. The error is elsewhere in the code.

or

3. There is a compiler bug. One very wild guess in this direction...
this probably is not really it, but it caught my eye... I still
occasionally see bugs in some compilers relating to lower bounds other
than 1, which you have.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Michael Metcalf

2006-09-19, 7:02 pm


"Mathemagician" <mathemagician@gmx.net> wrote in message
news:1158679883.809190.55760@i42g2000cwa.googlegroups.com...
>
> dat => plotdata(1)%p
>
> supposed to do ? Point at the exact same entity as the original, I
> would except.


The following code works as expected, so there's something important you're
not showing us.

Regards,

Mike Metcalf

implicit none
integer i
type real_matrix_pointer
real, dimension (:,:), pointer :: p
end type real_matrix_pointer

type (real_matrix_pointer) :: plotdata(0:3)

real, dimension(:,:), pointer :: dat

allocate(plotdata(1)%p(1,20))

plotdata(1)%p(1,:) = (/(i, i = 1, 20)/)

dat => plotdata(1)%p

write (6,*) plotdata(1)%p(1,1:20)
write (6,*) dat(1,1:20)
end


Mathemagician

2006-09-19, 7:02 pm

Thanks for the answers so far.

Primarily I wanted to know whether I should expect both pointers to
refer to the same thing in the first place, so that has been answered.

As to what the important thing should be that I'm not showing, I can't
tell. There is a lot more code in the program of course, but I don't
see where that would influence the situation. The original variable
"plotdata" works as expected in one line and in the next line the local
pointer "dat" does not. Before the declaration of dat and the output,
there really isn't much going on. Now I changed the source code so that
it is just declaration (of dat), pointer assignment and output with
nothing in between and I get the same behaviour.
Did you test it on the same compiler that I was using ?

Also, when I change "plotdata" to dimensions (1:3), (3) or (2:3) I
always get a similar problem. Only the order of the numbers differs,
but that's probably since the structure of "plotdata" is different, so
whatever gets the order wrong now gets it wrong in different ways.

Mathemagician

2006-09-19, 7:02 pm

One thing that may be relevant is that the definiton of type
"real_matrix_pointer" occurs in a separate module that is being used by
the module where the problem appears.

glen herrmannsfeldt

2006-09-19, 7:02 pm

Mathemagician <mathemagician@gmx.net> wrote:

> I have the following definition for a pointer to a 2-dimensional real
> matrix


> type real_matrix_pointer
> real, dimension (:,:), pointer :: p
> end type real_matrix_pointer


> and the following data of that type


> type (real_matrix_pointer) :: plotdata(0:3)


> Then, in a subroutine I have the variable


> real, dimension(:,:), pointer :: dat


> and the pointer assignment


> dat => plotdata(1)%p


Some thoughts, though I don't know the answer yet.

When/where is the data that plotdata(1)%p points to allocated?

Where does it get values assigned to it?

Where do the dimensions come from?

How is plotdata passed to the subroutine?

I am wondering if there is a way (bug or not) that dat could
point to an array with different dimensions that plotdata(1)%p.

It might be that I don't understand pointers to arrays, but
how does the dimension information get passed dat?

-- glen
Michael Metcalf

2006-09-19, 7:02 pm


">
> Also, when I change "plotdata" to dimensions (1:3), (3) or (2:3) I
> always get a similar problem. Only the order of the numbers differs,
> but that's probably since the structure of "plotdata" is different, so
> whatever gets the order wrong now gets it wrong in different ways.
>


Please be aware that if an array pointer dereferences another array that has
any lower bounds that are /= 1, then the corresponding lower bounds of the
pointer are nevertheless 1 (see "Fortran 95/2003 Explained", Section 6.15).

Also, as has been mentioned, the data type must be defined in one and only
one place (typically a module that is USEd).

HTH,

Mike Metcalf


Brooks Moses

2006-09-20, 7:01 pm

Mathemagician wrote:
> As to what the important thing should be that I'm not showing, I can't
> tell. There is a lot more code in the program of course, but I don't
> see where that would influence the situation. The original variable
> "plotdata" works as expected in one line and in the next line the local
> pointer "dat" does not. Before the declaration of dat and the output,
> there really isn't much going on.


This is where the process of creating a "minimal complete example" is
useful. The phrasing of the concept is from the TeX world, but it's a
generally applicable idea, and very valuable for general debugging as
well as for asking questions on newsgroups.

Essentially, given your very large program, and this bug that it
exhibits, you want to generate a program with the following
characteristics: Example (it exhibits the bug in question), Complete (it
can be compiled directly without modification or adding other files that
only you have copies of), and Minimal (nothing of substance can be
removed without losing the other two properties).

There are a couple of ways to generate such an example -- either you
want to start with an empty program and add things from your large
program until you reproduce the bug, or you want to start with a copy of
your large program and delete everything that you can without making the
bug go away. Generally, this is a process of experimentation -- adding
or deleting a block of code, testing to see if the bug is present, and
then reverting the addition or deletion if necessary.

Ideally, at the end of this process, you will have a program that's
somewhere around 20 lines or so (if not shorter), which you could post
to the newsgroup, and people could easily read and understand.

> Now I changed the source code so that
> it is just declaration (of dat), pointer assignment and output with
> nothing in between and I get the same behaviour.


But it can't be "just" that, because you say you still have the
definition of real_matrix_pointer in a separate module, and that
description also doesn't include how plotdata() gets declared, how it
gets its data, and how it gets moved into the subroutine where dat is
pointed at it.

In particular, it seems not at all impossible that you may be passing
plotdata into the subroutine in a way that complicates things, or that
causes it to not have at all the declaration you expected.

> Did you test it on the same compiler that I was using ?


Did you? You have an installed copy of that compiler, whereas Michael
(probably) does not, and his example is a trivially short program which
should only take a couple of minutes to test. :)

If you did try it, what happened? What results got printed out?

- Brooks


--
The "bmoses-nospam" address is valid; no unmunging needed.
Mathemagician

2006-09-21, 7:03 pm

> This is where the process of creating a "minimal complete example" is
> useful.


Thanks for the tipp. I've intuitively done that before, but I wasn't
aware that it's a common concept.
Thank you also for subtly hinting (which I believe you have done) that
I should put some more effort into the problem myself instead of just
relying on answers from others. I didn't intend to be particulary lazy,
I just wasn't able to put much more time and energy into it during the
last days.

Anyway, that being said, back to the problem.

> and how it gets moved into the subroutine where dat is pointed at it.


I guess I must apologize. I forgot to mention two things:

- The data isn't passed into the subroutine. It is a global variable
(of the module where the subroutine showing the problem is located).

- The data field is actually allocated in a third variable,
"originaldata", to which "plotdata" points in the first place. I wasn't
aware of the possibility to allocate from the pointer variable directly
until I studied Mike's example, therefore I didn't realize earlier that
this was relevant. I'm sorry for the confusion.

Anyway, I tested Mike's example and it already displays the problem on
my compiler.
I get the expected numbers 1, 2, ..., 20 (as reals) for the first
(plotdata) output, but 1, 5, 9, 13, 17 and a lot of 0's for "dat".

Moreover, when I change the dimension for "plotdata" in Mike's example
to (3) or (0:4), The offset between two consecutive numbers in "dat" is
always the size of the "plotdata" array.

Now if I allocate memory for plotdata 0, 2 and 3 to the same dimensions
as index 1,

allocate(plotdata(0)%p(1,20)) ! added
allocate(plotdata(1)%p(1,20))
allocate(plotdata(2)%p(1,20)) ! added
allocate(plotdata(3)%p(1,20)) ! added

I get a runtime error of "reference to undefined variable".

Next I initialize all the others with 1:

plotdata(0)%p(1,:) = 1 ! added
plotdata(1)%p(1,:) = (/(i, i = 1, 20)/)
plotdata(2)%p(1,:) = 1 ! added
plotdata(3)%p(1,:) = 1 ! added

The result for "plotdata" is the same. However, "dat" now displays:

1 5 9 13 17 0 1
1 1 1 1 0 1 1
1 1 1 0 0 0

It seems that the dimensions, allocation status and content of the
other plotdata fields influence what exactly is in "dat". But I can't
figure out a system.

Barring any solution for this, I guess the only option I have is to use
the original data field instead of another pointer, even if this makes
the code less readable.

Rainer

Richard E Maine

2006-09-21, 7:04 pm

Mathemagician <mathemagician@gmx.net> wrote:

>
> Thanks for the tipp. I've intuitively done that before, but I wasn't
> aware that it's a common concept.


Oh. Absolutely. And to let you in on a "secret" :-) ... if you are good
at it, and put in the work (it can be a bit of work at times), compiler
developers come to appreciate you a lot. In NAG's early days of 15 years
ago, back when it was the first release of the first f90 compiler and
had lots of bugs, I submitted lots of bug reports (over 100 eventually).
I'm sure that my bug reports got priority treatment, not because anyone
at NAG had ever heard of me before (I wasn't yet on J3 or otherwise well
known in global Fortran circles), but because the developers noticed
that my bug reports tended to:

1. Be about actual bugs in the compiler instead of just errors in my own
code.

and

2. Include minimal complete examples that made it very easy for the
developer to find the bugs.

They like that a lot better than getting an 8,000-line mess of a
program, with the complaint that it "doesn't work" (no further details),
where the problem turns out to be a user code error. I've seen ones like
that.

> Anyway, I tested Mike's example and it already displays the problem on
> my compiler.


THat seems like pretty strong evidence of a compiler bug, then. And
Mike's example is an excellent (as I'd expect from him) "minimal
complete example" well suited for a bug report. If you still have
support contacts for the compiler, I'd suggest submitting it as a bug
report. On the other hand, maybe the "if" in the previous sentence is a
pretty big one. I recall the Salford compiler getting sold and
remarketted under a different name, so if yours is still called Salford,
odds are that it isn't a current supported version... though I haven't
done anything actually useful like research the version number you
cited.

> Barring any solution for this, I guess the only option I have is to use
> the original data field instead of another pointer, even if this makes
> the code less readable.


I'd frankly be concerned about other pointer-related things with the
compiler until I managed to figure out exactly what conditions trigger
the apparent bug. It seems pretty basic.

--
Richard Maine | Good judgment comes from experience;
email: my first.last at org.domain| experience comes from bad judgment.
org: nasa, domain: gov | -- Mark Twain
Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2008 codecomments.com