credondo
credondo

Reputation: 744

Fortran pointer array to multiple targets

Is there a way to have in Fortran a pointer to an array pointing different targets?

The following code shows what I am trying to do, which does not work as I want since the second association overwrites the first

implicit none
integer, parameter  :: n = 3
integer, target     :: a(n), b(n)
integer, pointer    :: c(:) => NULL()

a = 4
b = 5

c(1:n) => a(1:n)
c(n+1:2*n) => b(1:n)

c(1:2*n) = 1

print*, a
print*, b

OUTPUT (ifort)
       4           1           1
       1           1           1
OUTPUT (gfortran)
       4           4           4
       1           1           1

And, any idea why ifort and gfortran behave differently in this case?

Upvotes: 1

Views: 349

Answers (1)

Ian Bush
Ian Bush

Reputation: 7432

No, there is no simple way to do this, at least as far as I can see. Maybe if you say why you are trying to do this somebody might come up with a suitable answer, for instance in my mind derived types and/or array constructors might be the way to go but without context it is difficult to say.

As for why you get different answers you accessed an array out of bounds so anything can happen:

ian@ian-pc:~/test/stack$ cat point.f90
Program point

  implicit none
  integer, parameter  :: n = 3
  integer, target     :: a(n), b(n)
  integer, pointer    :: c(:) => NULL()

  a = 4
  b = 5

  c(1:n) => a(1:n)
  c(n+1:2*n) => b(1:n)

  c(1:2*n) = 1

  print*, a
  print*, b

End Program point
ian@ian-pc:~/test/stack$ nagfor -C=all -C=undefined point.f90
NAG Fortran Compiler Release 5.3.1(907)
[NAG Fortran Compiler normal termination]
ian@ian-pc:~/test/stack$ ./a.out
Runtime Error: point.f90, line 14: Subscript 1 of C (value 1) is out of range (4:6)
Program terminated by fatal error
Aborted (core dumped)

Think carefully what the lines

  c(1:n) => a(1:n)
  c(n+1:2*n) => b(1:n)

are doing. The first line says forget about whatever c was before, now c( 1:n ) is an alias for a( 1:n ). Note the allowed indices for c run from 1 to n. Similarly the second line throws away the reference to a and says c( n+1:2*n) is an alias for b( 1:n ). Note now the indices of C run from n+1:2*n, while for b they run from 1:n, but this is fine as both have n elements and that is all that matters. However the next line says

 c(1:2*n) = 1

which can not be correct as you have just said the lowest allowed index for C is n+1, and as n=3 1 is not a valid index. Thus you are out of bounds and so anything can happen.

I strongly suggest when developing you use the debugging options on the compiler - in my experience it can save you hours by avoiding this kind of thing!

Upvotes: 3

Related Questions