bfletch
bfletch

Reputation: 411

In Fortran, does slicing an array create a copy in memory?

Say I pass a slice of an array into a subroutine that manipulates its inputs:

some_subroutine(a(:,1))

Is that section of the original a altered, or is some copy of a(:,1) altered?

Upvotes: 6

Views: 4599

Answers (2)

francescalus
francescalus

Reputation: 32366

There are a couple of other answers, which perhaps address slightly different (but relevant) points. Here I'll attempt to reconcile them.

Vladimir F's answer looks at the so-called copy-in/copy-out mechanism; bfletch's answer the final effect on the argument.

In general, the effect of the following

integer i(2,2)
i=0
call dosomething(i(1,:))   ! Just to make it not contiguous.

contains
  subroutine dosomething(j)
    integer j(2)  ! or j(*), or j(:)
    j=1
  end subroutine
end program

is that the array i has some elements set to 1 and the others 0. So, yes: regardless of whether there is a temporary copy (as from one answer) what can be observed after the call is that it's the actual argument itself that is modified.

Naturally, there is an exception: the value attribute.1 If the subroutine above is instead like

subroutine doseomthing(j)
  integer, value :: j(2)
  j=1
end subroutine

then there is indeed a true copy of the argument. Modifications to the dummy argument j are not reflected in the actual argument the section of i.


1This is for current Fortran. Fortran 90, as tagged, hasn't this feature.

Upvotes: 6

That depends if a is itself contiguous and how does some_subroutine look like.

You probably silently assume a is contiguous, but it doesn't have to be if a is itself some slice passed as an assumed-shape array or an array pointer.

Even if a is not contiguous and hence a(:,1) also isn't, a copy will not be needed if some_subroutine accepts an assumed shape argument

subroutine some_sub(b)
  real :: some_sub(:)

Upvotes: 5

Related Questions