fortran90 에서 assumed size array를 초과해서 assign하게 되면 어떻게 되나요?
연구분야에서 fortran90을 아직까지도 활발히 쓰고 있어 계속해서 접하고 사용하고 있는데요, 평소 assumed shape array까지만 사용하고 assumed size array는 별로 사용하고 있지 않다가 최근에 접할 일이 있어 살펴보고 있습니다.
그런데 당연히 컴파일단 아니면 실행단에서 에러가 날 줄 알았던 아래 코드가 에러 없이 작동을 하더라고요.
-----------------------------------
program main
implicit none
real*8 :: tot_array(10)
external :: assign_A
tot_array = 1.d0 ! tot_array 를 1.d0 초기화
call assign_A(tot_array(5)) ! tot_array 의 5번 element 부터 새롭게 덮어씀
end program
subroutine assign_A(A)
implicit none
real*8, intent(inout) :: A(*) ! assumed size array
integer :: i
do i = 1,10
A(i) = 2.d0
enddo
end subroutine
-----------------------------------
저는 위의 코드를 적을 때 당연히 길이가 10 인 tot_array 라는 녀석의 5번째 요소부터 10개를 수정하고 하니 당연히 원래의 tot_array의 크기를 초과하게되고, 따라서 최소한 코드 실행 시에 배열 bound를 초과했다는 에러가 뜰 줄 알았는데 그런 에러가 뜨지 않더군요.
그러면 아마도 tot_array(5)의 주소값에서부터 시작해 인접해있는 10개의 주소들에 2.d0 이라는 값을 집어넣어버렸다는 말이 되는 것 같은데요, 첫 6개 주소야 원래 tot_array 에 할당되어있던 친구들이니 괜찮다고 쳐도 마지막 4개 주소는 프로그램이 돌면서 어떤 변수가 할당되었을지 모를 주소가 아닌가요?
이런 미지의(?)주소에 들어있는 값을 함부러 변형시키는 코드를 컴파일러가 잡아주지 않는다면 나중에 코드를 짤 때 assumed size array의 한계를 한 번 잘못 초과했다가는 굉장히 원인 파악이 힘든 에러가 생길 수도 있을 것 같아 assumed size array를 쓰는게 굉장히 위험한 짓인 것 처럼 보이는데요, 또 막상 구글에서 글을 읽다보면 assumed size array를 쓰는게 위험하다라고 명시하는 곳은 없고 오히려 'assumed shape array에 비해 구식인 표현이 전혀 아니며, 아직도 사용이 권장된다' 라는 느낌의 글이 보이곤 하더라고요.
질문 정리하면 아래 두가지입니다.
1. 위 코드에서 메모리 상에서 'tot_array' 바로 옆에 가령 1.d0 의 값을 갖는 'b'라는 변수가 있었다면, 그 'b' 변수의 값이 2.d0으로 바뀐 것인가요?
2. 그게 아니라면 assign_A 서브루틴에서 tot_array(5)로부터 10개의 주소값에 2.d0을 넣으라고 했지만 실제로는 tot_array의 bound에 해당하는 tot_array(10) 까지만 2.d0 이 할당되고 남은 4개의 2.d0의 할당은 무시된건가요?
잘못된 코딩에 대한 구체적인 코드의 거동은 컴파일러의 종류에 따라 결정될 수 있습니다
문득 예전에 썼던 이 글이 보여 간략히 도움이 될 수도 있을 것 같은 StackOverFlow 포스트 링크 하나 남겨봅니다.
사실 몇 가지 print 로 뽑아봤으면 질문을 올릴 것도 없었던 것 같은데, 참 게을렀던 것 같네요. 저 때는 제가 코딩을 책에서 배우려고 노력했던 시기라...
https://stackoverflow.com/questions/61776293/difference-in-fortran-pointer-and-fortran-allocatable-in-calling-c-f-pointer
댓글 달기