ATTRIBUTES 지시문
ATTRIBUTES 지시문
컴파일러 지시문으로 변수와 프로시저에 표준에는 없는 세부 속성을 지정하는 방법을 다뤄요. 호출 규약이나 심볼 처리 방식, 최적화 힌트까지 원하는 대로 끼워 맞출 수 있죠.
본문
포트란 표준은 적법한 프로그램이 어떻게 동작해야 하는지는 정의하지만, 정확한 구현 방식은 표준화하지 않았어요. 그래서 사용자가 특정 구현 세부사항을 직접 고르도록, 표준에 없는 변수·프로시저의 속성(attribute)을 설정하는 데 **컴파일러 지시문(directive)**을 쓸 수 있어요. 어떤 속성이 지원되는지, 그 효과가 정확히 무엇인지는 운영체제와 프로세서에 따라 달라지는데, 자세한 내용은 *Using the GNU Compiler Collection (GCC)*의 C Extensions 부분을 보면 돼요.
프로시저와 프로시저 포인터에 대해 **호출 규약(calling convention)**을 바꾸는 데 쓸 수 있는 속성은 다음과 같아요.
CDECL— 표준 C 호출 규약STDCALL— 호출된 프로시저가 스택을 pop 하는 규약FASTCALL— 인자의 일부를 스택 대신 레지스터로 전달하는 규약
호출 규약을 바꾸는 것 외에도 이 속성들은 심볼 이름의 장식(decoration)에도 영향을 줘요. 예를 들어 앞에 밑줄을 붙이거나, 뒤에 @ 기호와 스택 바이트 수를 붙이는 식이죠. 프로시저를 프로시저 포인터에 할당할 때는 양쪽 모두 같은 호출 규약을 써야 해요.
일부 시스템에서는 프로시저와 전역 변수(모듈 변수와 COMMON 블록)가 공유 라이브러리 안에 있을 때 접근하려면 특별한 처리가 필요해요. 다음 속성들이 그 역할을 해요.
DLLEXPORT— DLL 안의 포인터에 대한 전역 포인터를 제공DLLIMPORT— 전역 포인터를 통해 함수나 변수를 참조
가상 인자(dummy argument)에는 NO_ARG_CHECK 속성을 쓸 수 있는데, 다른 컴파일러에서는 IGNORE_TKR라고도 불려요. 이 속성이 붙은 가상 인자에는 어떤 타입·종류의 실인자(TYPE(*)와 비슷하게), 어떤 등급(rank)의 스칼라·배열(포트란 표준에는 대응이 없음)이든 다 받아들여져요. TYPE(*)처럼 이 인자는 무한 다형(unlimited polymorphic)이라 타입 정보를 쓸 수 없어요. 게다가 이 인자는 NO_ARG_CHECK 속성이 붙은 가상 인자에게만 전달할 수 있고, PRESENT 내장 함수와 ISO_C_BINDING 모듈의 C_LOC의 인자로만 쓰일 수 있어요.
NO_ARG_CHECK 속성을 가진 변수는 assumed-type(TYPE(*); 권장)이거나 INTEGER, LOGICAL, REAL, COMPLEX 타입이어야 해요. 그리고 ALLOCATE, CODIMENSION, INTENT(OUT), POINTER, VALUE 속성을 가져선 안 되며, 스칼라이거나 assumed-size(dimension(*))여야 해요. TYPE(*)처럼 NO_ARG_CHECK 속성도 **명시적 인터페이스(explicit interface)**가 필요해요.
NO_ARG_CHECK— 타입·종류·등급 검사를 끔DEPRECATED— 그렇게 태그된 deprecated 프로시저·변수·파라미터를 사용할 때 경고를 냄. 경고는-Wno-deprecated-declarations로 끌 수 있어요.NOINLINE— 주어진 함수의 인라이닝을 막음INLINE— 주어진 함수를 인라인하라는 힌트. 단 인라이닝 크기 제한은 여전히 존중하며, C의inline키워드에 해당해요ALWAYS_INLINE— 인라이닝 크기 제한을 무시하고 주어진 함수를 강제로 인라인.NOINLINE의 반대편에 있고 C의always_inline속성에 해당해요.INLINE과ALWAYS_INLINE은NOINLINE과 함께 쓸 수 없고, 같은 프로시저에 둘 다 지정하면 경고와 함께 인라인 속성이 무시돼요NORETURN— 주어진 함수가 반환하지 않는다는 힌트를 추가WEAK— 외부 심볼 선언을 전역(global)이 아니라 약한 심볼(weak symbol)로 내보냄. 주로 사용자 코드에서 오버라이드할 수 있는 라이브러리 함수를 정의할 때 유용하고, 함수가 아닌 선언에도 쓸 수 있어요. 오버라이드하는 심볼은 약한 심볼과 같은 타입이어야 해요
속성은 다음 문법으로 지정해요.
!GCC$ ATTRIBUTES attribute-list :: variable-list
free-form 소스 코드에서는 !GCC$ 앞에 공백만 허용되고, fixed-form 소스 코드에서는 !GCC$, cGCC$, *GCC$가 첫 열에서 시작해야 해요.
프로시저의 경우 컴파일러 지시문은 프로시저 본문 안에, 변수와 프로시저 포인터의 경우에는 그 변수·포인터와 같은 선언부(declaration part)에 놓아야 해요.
더 알아보기
- GNU Fortran 컴파일러 지시문 개요
- UNROLL 지시문
- C 호출 규약과 ABI 처리