IDL을 사용하다보면 유저가 직접 작성한 프로그램 외에도 다른 유저들에 의하여 작성된 IDL 프로그램들을 받아서 사용하게 되는 경우가 꽤 있습니다. 이러한 외부 IDL 라이브러리의 프로그램들을 받아서 그 내용을 보면 맨 앞부분에 COMPILE_OPT라는 일종의 선언문이 사용된 경우들을 종종 보게 됩니다. 그래서 이 COMPILE_OPT 선언문을 별로 사용해보지 않은 유저라면 이것이 대체 어떤 목적으로 사용되는 것인지 궁금할 수도 있을 것입니다. 사실 COMPILE_OPT는 일종의 선언문(Statement)으로서 IDL의 프로시저 및 함수형 프로그램에서 몇가지 기본적인 설정들을 인위적으로 강제하는 역할을 합니다. 이렇게만 표현하면 다소 막연하게 느껴질 수도 있으므로 그 내막을 좀 들여다보기로 하겠습니다. 일단 IDL 도움말에서 COMPILE_OPT를 사용하는 문법을 살펴보면, 다음과 같이 구체적인 설정을 위한 단일 또는 복수의 인자들이 붙는 방식입니다.
COMPILE_OPT opt1, [opt2, opt3, ...]
그리고 IDL 도움말에서 COMPILE_OPT에 관한 섹션을 보면 사용 가능한 인자들 및 해당 기능에 대한 설명이 자세히 소개되어 있습니다. 일단 여기서는 가장 많이 사용되는 주요 인자들인 DEFINT32 및 STRICTARR에 관하여 살펴보겠습니다.
< DEFINT32 >
첫번째로 주목해볼 인자는 DEFINT32라는 인자입니다. 이러한 인자를 사용하는 방식은 다음과 같습니다.
COMPILE_OPT DEFINT32
이러한 문구를 프로시저나 함수 프로그램의 맨 앞부분에 명시할 수도 있고 또는 그냥 IDL의 커맨드 입력창에서 사용할 수도 있습니다. 어쨌든 이러한 선언문이 명시되면 이후부터는 정수형의 값을 무조건 4바이트(32비트) 정수형(Long Integer)으로 인식합니다. 원래 IDL에서 정수형 값을 정의하면 일단은 2바이트(16비트)의 일반 정수형으로 인식되는 것이 기본적인 설정인데, 이러한 기본 설정 자체를 아예 변경하는 것입니다. 예를 들어서 30000+10000이라는 정수형 값들 사이의 연산을 하고 그 결과를 출력하는 프로그램을 봅시다.
PRO test_compile_opt
a = 30000
b = 10000
c = a+b
HELP, a, b, c
PRINT, c
END
위와 같은 프로그램을 실행하면 그 결과는 다음과 같이 출력될 것입니다.
A INT = 30000
B INT = 10000
C INT = -25536
-25536
이와 같이 수학적으로 전혀 맞지 않는 결과가 나오는 이유는 변수 a, b 모두 2바이트 일반 정수형 값으로 정의되고 이들 사이의 연산 결과인 변수 c 역시 동일한 자료형이 되기 때문입니다. 2바이트 정수형 값은 유효 범위가 -32768~+32767이기 때문에 수학적인 연산 결과인 40000이라는 값을 가질 수 없게 됩니다. 그래서 변수 a, b를 애초에 4바이트 정수(Long Integer)로 정의하여 이러한 문제를 해결하는 것이 통상적인 해결책입니다.
PRO test_compile_opt
a = 30000L
b = 10000L
c = a+b
HELP, a, b, c
PRINT, c
END
즉 이와 같이 변수 a, b에 대입되는 정수값에 알파벳 L을 붙여서 아예 4바이트 정수로 정의하면 다음과 같이 정상적인 결과를 얻게 됩니다.
A LONG = 30000
B LONG = 10000
C LONG = 40000
40000
하지만 다음과 같이 COMPILE_OPT DEFINT32 선언문을 명시할 경우에는 변수 a, b를 굳이 4바이트 정수형으로 정의하지 않고 그냥 일반 정수형처럼 정의해도 자동적으로 4바이트 정수형으로 인식되기 때문에 40000이라는 결과를 얻게 됩니다.
PRO test_compile_opt
COMPILE_OPT DEFINT32
a = 30000
b = 10000
c = a+b
HELP, a, b, c
PRINT, c
END
A LONG = 30000
B LONG = 10000
C LONG = 40000
40000
이와 같이 COMPILE_OPT에서 DEFINT32 인자를 명시하면 정수형 값을 무조건 4바이트(32비트) 정수형(Long Integer)으로 인식하게 됩니다. 따라서 유저의 의도에 따라서는 프로그램을 작성하는데 있어서 이러한 선언을 하는 것이 필요할 수도 있을 것입니다.
< STRICTARR >
두번째로 주목해볼 인자는 STRICTARR라는 인자입니다. 즉 다음과 같이 COMPILE_OPT에서 이러한 인자를 명시하는 경우입니다.
COMPILE_OPT STRICTARR
원래 IDL에서 배열의 인덱스를 명시할 때에는 꺾쇠괄호 [ ]를 사용하는 것이 기본이긴 하지만 일반괄호 ( ) 역시도 사용이 가능합니다. 그런데 위와 같은 선언문이 명시되면 그 이후부터는 배열의 값에 접근하기 위하여 인덱싱을 하는데 있어서 일반괄호 ( )를 사용하는 것이 완전히 금지됩니다. 그러면 배열을 하나 정의하고 배열 내 값들을 인덱싱하여 출력하는 다음과 같은 예제 프로그램을 살펴봅시다.
PRO test_compile_opt
a = INDGEN(11)*10
PRINT, a[3], a[6]
PRINT, a(3), a(6)
END
이와 같이 배열 내 특정한 값을 인덱싱하는데 있어서 [ ] 및 ( )를 모두 사용하였습니다. 출력 결과는 다음과 같습니다.
30 60
30 60
이와 같이 [ ] 및 ( ) 모두 사용이 가능합니다. 그러면 이번에는 프로그램의 시작 부분에 COMPILE_OPT STRICTARR 선언문을 명시해봅시다.
PRO test_compile_opt
COMPILE_OPT STRICTARR
a = INDGEN(11)*10
PRINT, a[3], a[6]
PRINT, a(3), a(6)
END
이러한 상태로 다시 실행해보면 결과는 다음과 같습니다.
30 60
% Attempt to call undefined function: 'A'.
이와 같이 에러가 발생하면서 프로그램의 실행이 중단됩니다. 정확히 얘기하면 여기서는 a가 배열이 아닌 함수 프로그램의 명칭으로 인식된 상태입니다. 원래 IDL에서는 함수형(Function) 프로그램을 사용할 때 그 인자들(Arguments)은 모두 일반괄호 ( )안에 명시하게 되어 있습니다. 그런데 배열 내 값에 접근하기 위하여 인덱스를 명시할 때에도 일반괄호 ( )를 사용할 수 있는 것이 기본입니다. 하지만 이와 같이 일반괄호 ( )의 사용 방식이 중복되기 때문에 혼란이 발생하는 경우도 종종 있습니다. 그래서 만약 IDL 프로그램 내에서 a(3)과 같은 문구가 있을 경우 원래 IDL은 먼저 'a'라는 이름의 함수 프로그램이 존재하는가 여부를 먼저 체크합니다. 만약 존재한다면 ( )안에 명시된 값들을 그 함수의 인자로 인식하게 됩니다. 하지만 그러한 함수 프로그램이 존재하지 않을 경우에는 'a'를 배열의 명칭으로 간주하고 작업을 진행합니다. 따라서 우연치않게 동일한 이름의 배열과 함수가 함께 존재할 경우, 전혀 생각하지도 못했던 결과가 나올 위험성이 충분히 있습니다.
이러한 이유로 인하여 일반적으로는 배열의 인덱스를 명시할 때에는 가급적이면 ( )를 쓰지않고 무조건 [ ]를 사용하는 것이 권장되는 경우가 많습니다. 하지만 이것은 그야말로 "권장사항"일 뿐이므로 유저가 만약 굳이 ( )를 사용하여 배열 인덱싱을 한다고 해도 막을 방법은 없습니다. 그런데 위와 같이 COMPILE_OPT STRICARR 선언문을 명시하면 배열의 인덱싱에 있어서 ( )를 아예 사용하지 못하도록 강제하는 역할을 합니다. 이러한 명령이 실행된 상태에서는 IDL은 일반괄호 ( )의 앞에 명시된 문구(여기서는 'a')를 무조건 함수 프로그램의 이름으로 간주합니다. 배열일 가능성 자체를 아예 배제해버리는 것입니다. 이렇게 하면 프로그래밍에 있어서 쓸데없는 혼란의 가능성을 사전에 차단해버리는 효과를 얻을 수 있습니다.
그래서 COMPILE_OPT에서 일반적으로 많이 사용되는 두가지 인자들은 이와 같습니다. 만약 두 인자를 모두 사용하려면 다음과 같이 두 인자를 함께 명시하면 됩니다.
COMPILE_OPT DEFINT32, STRICTARR
하지만 다음과 같이 IDL2라는 인자 하나만 사용하면 위의 두 인자를 둘 다 명시한 것과 같은 효력을 갖습니다.
COMPILE_OPT IDL2
그래서 이와 같이 사용하는 경우가 더 많습니다. 아마 이러한 문구는 외부로부터 받아온 IDL 프로그램들을 보면 자주 보일 것입니다. 따라서 이러한 문구에 담긴 의미를 잘 알아두면 그 프로그램의 내용을 이해하는데 있어서 분명히 도움이 될 것입니다. 그리고 COMPILE_OPT에는 그 외에도 다른 인자들 및 비교적 최근에 도입된 새로운 인자들도 지원되는데, 이와 관련해서는 다음 회차에서 다뤄보기로 하겠습니다.
* 이 내용은 지난 2011년에 올렸던 게시물의 내용을 수정 및 보강하여 다시 새롭게 올리는 것입니다. 따라서 기존의 게시물은 삭제하고 이번에 작성한 게시물로 대체합니다.
* 이 글이 도움이 되었다면 게시물에 대하여 공감 버튼(하트 모양) 클릭 및 블로그 구독도 해주시면 더 큰 힘이 됩니다. 감사합니다.
'IDL > Programming' 카테고리의 다른 글
| HttpRequest 클래스의 FILENAME 키워드 사용법 (0) | 2025.08.25 |
|---|---|
| COMPILE_OPT 선언문의 이해 [2] (6) | 2025.07.24 |
| 날짜 기반의 이름을 갖는 파일들에 대한 접근법 (3) | 2025.07.01 |
| FILE_COPY 및 FILE_MOVE 명령 (1) | 2025.06.20 |
| FOREACH 구문 소개 (0) | 2025.05.26 |