답변
아마도 약간 해결 다른 답변의 몇 가지가있다 다른 (그러나 관련된) 점. 여기서 나는 그것들을 조화 시키려고 노력할 것이다.
Vladimir F's answer은 소위 카피 인/카피 아웃 메커니즘을 사용합니다. bfletch's answer 인수에 대한 최종 효과. 일반적
다음
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
효과는 어레이가 i
1
설정된 일부 요소와 다른 0
를 갖는다는 것이다. 따라서 yes : 임시 복사본이 있는지 여부에 관계없이 (호출 한대로) 호출 후에 관찰 할 수있는 것은 수정 된 실제 인수 자체라는 점입니다.
자연히 예외가 있습니다 : value
속성. 1 서브 루틴 위
subroutine doseomthing(j)
integer, value :: j(2)
j=1
end subroutine
다음 실제로 인수의 진정한 사본이 대신 같은 경우. 가짜 인수
j
에 대한 수정은
i
섹션의 실제 인수에 반영되지 않습니다.
1이 현재 포트란을위한 것입니다. 태그가있는 Fortran 90에는이 기능이 없습니다.
이제 OP의 실제 의도를 더 잘 읽었을 것 같습니다. 문제는 제목이 "사본을 메모리에 만듭니다"이지만 최종 질문은 원본이 수정되었는지 여부입니다. –
저는 이것이 단지 스스로 대답하는 질문이라는 것을 눈치 챘지만 그 맥락에서 임시 복사본에 관해서는 확실히 말할 가치가 있습니다. 아마도 나는 또한 추가 할 수 있습니다 : 복사본을 만드는 슬라이싱에 관한 것은 없으며 여기서 슬라이스가 인수 일 때만 보겠습니다. 배열 슬라이스 할당에는 임시 복사본이 필요할 수도 있습니다. – francescalus
a
자체가 연속적인지, some_subroutine
과 같은지에 따라 달라집니다.
a
은 연속적이라고 가정 할 수도 있지만, a
자체가 가정용 모양 배열 또는 배열 포인터로 전달 된 일부 슬라이스 일 필요는 없습니다.
하더라도 a
는 some_subroutine
는 가정 된 형태 인수를 받아들이는 경우, 사본이 필요하지 않습니다되지 따라서 a(:,1)
도하지 연속이며
subroutine some_sub(b)
real :: some_sub(:)
gfortran의 경우 "-Warray-temporaries"또는 "-fcheck-array-temporaries"옵션은 임시 정보에 대한 정보를 얻는 데 유용합니다. 또한 실제 배열과 더미 배열의 첫 번째 요소의 주소를 어떻게 든 인쇄하여 동일한 메모리 (예 : c_loc() 또는 loc())를 가리키는 지 확인할 수 있습니다. – roygvib