Pragma 지시문 및 __pragma
_Pragma
키워드
Pragma 지시문은 컴퓨터별 또는 운영 체제별 컴파일러 기능을 지정합니다. 지시문으로 #pragma
시작하는 줄은 지시문을 pragma 지정합니다. Microsoft 관련 __pragma
키워드를 사용하면 매크로 정의 내에서 지시문을 코딩 pragma 할 수 있습니다. C99에서 도입되고 C++11에서 채택된 표준 _Pragma
전처리기 연산자는 비슷합니다.
구문
#pragma
token-string
__pragma(
token-string)
두 개의 선행 밑줄 - Microsoft 관련 확장
_Pragma(
string-literal)
C99
설명
C 및 C++의 각 구현은 호스트 컴퓨터나 운영 체제에 고유한 기능을 몇 가지 지원합니다. 예를 들어 일부 프로그램은 메모리의 데이터 위치를 정확하게 제어하거나 특정 함수가 매개 변수를 받는 방식을 제어해야 합니다. 이 지시문은 #pragma
C 및 C++ 언어와의 전반적인 호환성을 유지하면서 각 컴파일러가 컴퓨터 및 운영 체제 관련 기능을 제공하는 방법을 제공합니다.
Pragma 지시문은 정의에 따라 컴퓨터별 또는 운영 체제에 따라 다르며 일반적으로 모든 컴파일러에 대해 다릅니다. 조건부 지시문에서 A pragma 를 사용하여 새 전처리기 기능을 제공할 수 있습니다. 또는 구현 정의 정보를 컴파일러에 제공하는 데 사용합니다.
토큰 문자열은 특정 컴파일러 명령 및 인수(있는 경우)를 나타내는 일련의 문자입니다. 숫자 기호(#
)는 줄에서 공백이 pragma아닌 첫 번째 문자여야 합니다. 공백 문자는 숫자 기호와 단어 "pragma"를 구분할 수 있습니다. 다음으로 #pragma
변환기에서 전처리 토큰으로 구문 분석할 수 있는 텍스트를 작성합니다. 인수 #pragma
는 매크로 확장의 적용을 받습니다.
문자열 리터럴은 에 대한 입력_Pragma
입니다. 외부 따옴표 및 선행/후행 공백이 제거됩니다. \"
가 대체 "
되고 \\
.로 \
대체됩니다.
컴파일러는 인식할 수 없는 경고를 발견하고 pragma 컴파일을 계속합니다.
Microsoft C 및 C++ 컴파일러는 다음 pragma 지시문을 인식합니다.
alloc_text
auto_inline
bss_seg
check_stack
code_seg
comment
component
conform
1
const_seg
data_seg
deprecated
1 C++ 컴파일러에서만 지원됩니다.
Pragma 지시문 및 컴파일러 옵션
일부 pragma 지시문은 컴파일러 옵션과 동일한 기능을 제공합니다. pragma 소스 코드에 도달하면 컴파일러 옵션에서 지정한 동작을 재정의합니다. 예를 들어 지정한 /Zp8
경우 다음을 사용하여 코드 pack
의 특정 섹션에 대해 이 컴파일러 설정을 재정의할 수 있습니다.
cl /Zp8 some_file.cpp
// some_file.cpp - packing is 8
// ...
#pragma pack(push, 1) - packing is now 1
// ...
#pragma pack(pop) - packing is 8 again
// ...
__pragma
키워드
컴파일러는 지시문과 동일한 기능을 #pragma
포함하는 Microsoft 관련 __pragma
키워드도 지원합니다. 차이점은 키워드가 __pragma
매크로 정의에서 인라인으로 사용할 수 있다는 것입니다. 컴파일러가 #pragma
지시문의 숫자 기호 문자('#')를 문자열화 연산자(#)로 해석하기 때문에 이 지시문은 매크로 정의에서 사용할 수 없습니다.
다음 코드 예제에서는 키워드를 __pragma
매크로에서 사용할 수 있는 방법을 보여 줍니다. 이 코드는 "컴파일러 COM 지원 샘플"의 ACDUAL 샘플에 있는 mfcdual.h 헤더에서 발췌되었습니다.
#define CATCH_ALL_DUAL \
CATCH(COleException, e) \
{ \
_hr = e->m_sc; \
} \
AND_CATCH_ALL(e) \
{ \
__pragma(warning(push)) \
__pragma(warning(disable:6246)) /*disable _ctlState prefast warning*/ \
AFX_MANAGE_STATE(pThis->m_pModuleState); \
__pragma(warning(pop)) \
_hr = DualHandleException(_riidSource, e); \
} \
END_CATCH_ALL \
return _hr; \
_Pragma
전처리 연산자
_Pragma
는 Microsoft 관련 __pragma
키워드와 유사합니다. C99의 C 표준과 C++11의 C++ 표준에 도입되었습니다. 또는 /std:c17
옵션을 지정하는 경우에만 C에서 /std:c11
사용할 수 있습니다. C++의 경우 기본값을 포함하여 모든 /std
모드에서 사용할 수 있습니다.
와 달리 #pragma
지시 _Pragma
문을 매크로 정의에 넣을 pragma 수 있습니다. 문자열 리터럴은 문 다음에 #pragma
배치할 문자열 리터럴이어야 합니다. 예시:
#pragma message("the #pragma way")
_Pragma ("message( \"the _Pragma way\")")
위에 표시된 대로 따옴표와 백 슬래시를 이스케이프해야 합니다. pragma 인식되지 않는 문자열은 무시됩니다.
다음 코드 예제에서는 어설션과 유사한 매크로에서 키워드를 사용하는 방법을 _Pragma
보여 줍니다. 조건 식이 상수일 때 경고를 표시하지 않는 지시문을 만듭니다 pragma .
매크로 정의는 단일 문처럼 사용할 수 있도록 다중 문 매크로에 관용구를 사용합니다 do ... while(0)
. 자세한 내용은 Stack Overflow의 C 다중 줄 매크로를 참조하세요. 예제의 문은 _Pragma
뒤에 있는 코드 줄에만 적용됩니다.
// Compile with /W4
#include <stdio.h>
#include <stdlib.h>
#define MY_ASSERT(BOOL_EXPRESSION) \
do { \
_Pragma("warning(suppress: 4127)") /* C4127 conditional expression is constant */ \
if (!(BOOL_EXPRESSION)) { \
printf("MY_ASSERT FAILED: \"" #BOOL_EXPRESSION "\" on %s(%d)", __FILE__, __LINE__); \
exit(-1); \
} \
} while (0)
int main()
{
MY_ASSERT(0 && "Note that there is no warning: C4127 conditional expression is constant");
return 0;
}