Conditional inclusion
전처리기는 소스 파일의 일부를 조건부로 컴파일하는 기능을 지원합니다. 이 동작은
#if
,
#else
,
#elif
,
#ifdef
,
#ifndef
,
#elifdef
,
#elifndef
(C23 이후)
, 그리고
#endif
지시자에 의해 제어됩니다.
목차 |
구문
#if
표현식
|
|||||||||
#ifdef
식별자
|
|||||||||
#ifndef
식별자
|
|||||||||
#elif
표현식
|
|||||||||
#elifdef
식별자
|
(C23 이후) | ||||||||
#elifndef
식별자
|
(C23 이후) | ||||||||
#else
|
|||||||||
#endif
|
|||||||||
설명
조건부 전처리 블록은
#if
,
#ifdef
또는
#ifndef
지시자로 시작하며, 선택적으로 임의의 수의
#elif
,
#elifdef
, 또는
#elifndef
(C23부터)
지시자를 포함할 수 있고, 선택적으로 최대 하나의
#else
지시자를 포함하며,
#endif
지시자로 종료됩니다. 내부의 모든 조건부 전처리 블록은 별도로 처리됩니다.
다음 각 지시문들
#if
,
#ifdef
,
#ifndef
,
#elif
,
#elifdef
,
#elifndef
(C23부터)
, 그리고
#else
는 첫 번째
#elif
,
#elifdef
,
#elifndef
(C23부터)
,
#else
,
#endif
지시문이 나올 때까지 코드 블록을 제어합니다. 단, 이는 내부 조건부 전처리 블록에 속하지 않는 지시문에 한합니다.
#if
,
#ifdef
및
#ifndef
지시자는 지정된 조건(아래 참조)을 검사하고 조건이 true로 평가되면 제어되는 코드 블록을 컴파일합니다. 이 경우 후속
#else
,
#elifdef
,
#elifndef
,
(C23부터)
및
#elif
지시자는 무시됩니다. 반대로 지정된 조건이 false로 평가되면 제어되는 코드 블록은 건너뛰고 후속
#else
,
#elifdef
,
#elifndef
,
(C23부터)
또는
#elif
지시자(있는 경우)가 처리됩니다. 후속 지시자가
#else
인 경우,
#else
지시자에 의해 제어되는 코드 블록은 무조건 컴파일됩니다. 그렇지 않으면
#elif
,
#elifdef
, 또는
#elifndef
(C23부터)
지시자는
#if
지시자인 것처럼 동작합니다: 조건을 확인하고, 결과에 따라 제어되는 코드 블록을 컴파일하거나 건너뛰며, 후자의 경우 후속
#elif
,
#elifdef
,
#elifndef
,
(C23부터)
및
#else
지시자를 처리합니다. 조건부 전처리 블록은
#endif
지시자로 종료됩니다.
조건부 평가
#if, #elif
표현식 은 상수 표현식으로, 상수 와 #define 지시문을 사용하여 정의된 식별자만 사용합니다. 리터럴이 아니고 #define 지시문을 사용하여 정의되지 않은 모든 식별자는 0 으로 평가되며, true 는 1 로 평가되는 경우는 예외입니다 (C23부터) .
표현식은 다음과 같은 형태의 단항 연산자를 포함할 수 있습니다:
defined
identifier
또는
defined (
identifier
)
이 연산자들은
identifier
가
#define
지시자를 사용하여 정의된 경우
1
을 반환하고, 그렇지 않으면
0
을 반환합니다.
이 문맥에서
__has_include
,
__has_embed
및
__has_c_attribute
는 정의된 매크로 이름처럼 취급됩니다.
(C23부터)
만약
expression
이 0이 아닌 값으로 평가되면 제어되는 코드 블록이 포함되고, 그렇지 않으면 건너뜁니다. 사용된 식별자가 상수가 아닌 경우
0
으로 대체됩니다.
|
전처리기 지시문의 맥락에서,
|
(C23부터) |
참고:
DR 412
이전까지,
#if
cond1
...
#elif
cond2
는
#if
cond1
...
#else
뒤에
#if
cond3
가 오는 경우와 다릅니다. 왜냐하면
cond1
가 참일 경우, 두 번째
#if
는 건너뛰어지고
cond3
는 올바른 형식일 필요가 없지만,
#elif
의
cond2
는 유효한 표현식이어야 하기 때문입니다.
DR 412
부터는 건너뛰어지는 코드 블록을 유도하는
#elif
도 건너뛰어집니다.
결합 지시문
식별자가 매크로 이름으로 정의되었는지 확인합니다.
#ifdef
identifier
는 기본적으로
#if defined
identifier
와 동등합니다.
#ifndef
identifier
는 기본적으로
#if !defined
identifier
와 동등합니다.
|
|
(C23부터) |
참고 사항
#elifdef
와
#elifndef
지시문은 C23을 대상으로 하지만, 구현체들은 이를 이전 언어 모드로 이식 가능한 확장 기능으로 제공할 수 있습니다.
예제
#define ABCD 2 #include <stdio.h> int main(void) { #ifdef ABCD printf("1: yes\n"); #else printf("1: no\n"); #endif #ifndef ABCD printf("2: no1\n"); #elif ABCD == 2 printf("2: yes\n"); #else printf("2: no2\n"); #endif #if !defined(DCBA) && (ABCD < 2 * 4 - 3) printf("3: yes\n"); #endif // C23 directives #elifdef/#elifndef #ifdef CPU printf("4: no1\n"); #elifdef GPU printf("4: no2\n"); #elifndef RAM printf("4: yes\n"); // selected in C23 mode, may be selected in pre-C23 mode #else printf("4: no3\n"); // may be selected in pre-C23 mode #endif }
가능한 출력:
1: yes 2: yes 3: yes 4: yes
결함 보고서
다음의 동작 변경 결함 보고서들은 이전에 발표된 C 표준에 소급 적용되었습니다.
| DR | 적용 대상 | 게시된 동작 | 올바른 동작 |
|---|---|---|---|
| DR 412 | C89 |
실패한
#elif
의 표현식이 유효해야 했음
|
실패한
#elif
는 건너뜀
|
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.10.1 조건부 포함 (p: TBD)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.10.1 조건부 포함 (p: 118-119)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.10.1 조건부 포함 (p: 162-164)
- C99 표준 (ISO/IEC 9899:1999):
-
- 6.10.1 조건부 포함 (p: 147-149)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 3.8.1 조건부 포함
참고 항목
|
C++ 문서
for
조건부 포함
|