Call by Value와 Call by Reference

다른 언어에 비해서 IDL에서는 Call by Value와 Call by Reference를 명시적으로 분류하지는 않고 있습니다. 이 때문에 함수에 쓰이는 인수가 함수의 작동이 끝나도 제대로 변환되어 있지 않는 경우도 있습니다. 이번 포스팅에서는 이 Call by Value와 Call by Reference를 비교해보고 IDL에서는 어떻게 쓰이는지 알아보고자 합니다.

C나 C++에서는 기본적으로 함수를 작성할 때 Call by Value와 Call by Reference를 명시적으로 구분해서 사용했습니다. 변수 a와  b를 더하는 함수를 작성한다고 하면,

위의 간단한 함수는 값으로 호출이 되었다는 것을 알 수 있습니다. 즉 이 함수에서 a와 b는  Call by Value인 것이지요.  또한 이와 동일한 기능으로 이런 함수를 작성해보도록 합시다.

여기서는 똑같은 기능을 하지만, 이 함수로는 a에 바로 두수의 합이 들어갑니다. 바로 a와 b가 참조로 호출이 되었기 때문이지요.

이처럼 C 혹은 C++에서는 함수를 작성할 때 인수를 값으로 부를지 참조로 부를지 명시적으로 표현을 합니다. 하지만 IDL에서는 다음과 같이 인수가 값으로 들어가는지, 참조로 들어가는지 모르게 쓰여져 있습니다.

위의 코드를 보시면 알겠지만, IDL에서는  Call by Value와 Call by Reference를 명시적으로 표현하고 있지는 않습니다. 이 때 중요한 점은 기본적으로 IDL에서는 Call by Reference를 이용한다는 점입니다. 따라서 위의 함수를 사용할 경우에 다음과 같이 결과 뿐만 아니라 들어간 인수도 변화하게 됩니다.

네 자연스럽게 data가 참조가 되었음을 알 수 있습니다. 하지만 다음과 같은 경우 Call by Value가 되게 됩니다.

함수를 보시면 위에 있던 data값을 그대로 이용했습니다. 그런데 결과를 보시면 data[3]의 값이 참조되지 않았다는 것을 알 수 있습니다. 즉 Call by Value가 된 것이지요. 기본적으로 IDL에서 이러한 일로 문제가 발생하는 것은 참조를 이용해서 인수에 값을 넣으려고 했는데 오류가 나는 상황이 될 겁니다. 기본적으로  Call by Reference이기 때문에 왜 안되냐 할 수 있지만, 다음과 같은 문법이 마지막에 되지 않으면 Call by Value가 된다고 합니다.(쓰여있지 않지만 실제로 작동한다고 합니다.)

이때 배열의 일부는 arg가 변화할 때 위 식이 다시 들어가지 않는 경우가 발생할 수도 있기 때문에 Call by Value로 함수가 작동하게 되지요. 이러한 문제가 발생하는 인수의 값은 다음과 같습니다.

상수, 배열의 일부, 구조체의 일부, 시스템 변수, 수식

이러한 인수들의 공통점은 위에 써있는 문법을 사용할 때 무조건 혹은 일정한 경우 오류가 나는 인수라는 것입니다. 따라서 안정성을 위해서 값을 받는 형식을 취하는 것이죠.

지금부터 실제 Call by Value로 인하여 발생하는 문제가 생기는 프로시저를 보도록 하겠습니다. 이것은why_error이라는 exmples/data/plot.txt를 불러오는 프로시저입니다.

이 코드를 실행시키면 다음과 같은 결과를 받게됩니다.

데이터를 제대로 받지 못했는데요. 이 코드에서 문제가 되는 부분은 다음과 같습니다.

time[i], theory[i], observe[i]는 배열의 일부이기 때문에 Call by Value로 작동하게 되는 것입니다. 따라서 이를 다음과 같이 바꾸어봅시다.

tmptime,tmptheory,tmpobserve라는 사용되지 않은 변수를 이용해서 이를 각 배열의 자리에 넣어보았습니다. 이름은 not_error로 하여 새로운 프로시저를 만들었습니다. 결과는 다음과 같이 출력됩니다.

제대로 출력이 된 것을 볼 수 있습니다.

이처럼 IDL에서 함수의 이용시 신경을 안쓰면 무심코 Call by Value를 이용하게 됩니다. 이러한 문제는 어떻게 보면 IDL의 변수나 함수의 이용이 쉽기 때문에 발생하게 되는데요. 어렵지는 않기 때문에 조심하지 않으면 자주 문제를 일으킬 것 같습니다. 모두들 이런점에 조심해서 코딩하셨으면 합니다.

이와 비슷한 문제로 상수값을 int로 두어서 결과값이 int로 나오는 경우도 있습니다. 이럴땐 숫자가 작아서 주로 0으로 나오는 경우지요.(경험담입니다.) IDL이 워낙 변수를 변환하기 쉬운 언어라서 이러한 문제들이 자주 발생하곤합니다. 위에서 쓴 것처럼 자주 문제를 일으키는데다가,  문법적으로 에러도 내지 않기 때문에 조심하지 않으면 큰일날지도 모릅니다. 추가적으로 위에 나와있는 IDL예제들은 Basic IDL Programming에서 가져왔습니다.  예제로서 참 좋네요.

One Comment

Comments are closed.