#if 0… #endif 블록은 정확히 무엇을합니까?


124

에서 C / C ++

#if 0/ #endif블록 사이에있는 코드는 어떻게됩니까 ?

#if 0

//Code goes here

#endif

코드가 단순히 건너 뛰어 실행되지 않습니까?


17
이것은 대량의 코드를 주석 처리하거나 코드 블록 포함 테스트를 허용하는 데 사용되는 기술입니다. 이 기능이 없으면 각 줄에 접두사를 붙이 //거나 섹션을로 시작하고 섹션을 /*로 끝내야합니다 */. 후자의 기술의 문제점은 주석이 중첩되지 않기 때문에 개발자가 */시작과 끝 사이에 모든 것을 확인하고 처리해야한다는 것 입니다.
Thomas Matthews

답변:


141

실행되지 않을뿐만 아니라 컴파일되지도 않습니다.

#if실제 컴파일 단계 전에 평가되는 전 처리기 명령입니다. 해당 블록 내부의 코드는 컴파일 된 바이너리에 나타나지 않습니다.

나중에 다시 켜기 위해 코드 세그먼트를 일시적으로 제거하는 데 자주 사용됩니다.


1
이것은 모든 종류의 의견에 해당됩니다. 중요한 차이점은 중첩입니다.
Samy Bencherif

73

한 가지 중요한 차이점을 제외하면 블록을 주석 처리하는 것과 동일합니다. 중첩은 문제가되지 않습니다. 이 코드를 고려하십시오.

foo();
bar(x, y); /* x must not be NULL */
baz();

주석을 달고 싶다면 다음을 시도해 볼 수 있습니다.

/*
foo();
bar(x, y); /* x must not be NULL */
baz();
*/

Bzzt. 구문 오류! 왜? 블록 코멘트 (당신이 SO의 구문 강조에서 볼 수있는 바와 같이) 그렇게하지 둥지 등을 할 수 있기 때문에 */단어 "NULL"후가 만드는 코멘트를 종료 baz주석하지 전화를하고, */이후에 baz구문 오류입니다. 반면에 :

#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif

전체 내용을 주석 처리합니다. 그리고 #if 0s는 다음과 같이 서로 중첩됩니다.

#if 0
pre_foo();
#if 0
foo();
bar(x, y); /* x must not be NULL */
baz();
#endif
quux();
#endif

물론 이것은 약간 혼란 스러울 수 있고 제대로 설명하지 않으면 유지 관리 문제가 될 수 있습니다.


5
#if 내부의 코드는 주석과 달리 어휘 적으로 정확해야하며 전 처리기 지시문은 여전히 ​​유효합니다 (동일 함).
jpalecek

@David : 어휘 적으로 정확하지는 않지만 여전히 컴파일됩니다. 따라서 코드가 어휘 적으로 정확할 필요는 없습니다.
Dennis Zickefoose

1
@Dennis, foo.c:3: unterminated string or character constantgcc에서 얻었습니다. 무엇을 사용하고 있습니까?
David X

18

컴파일러가 컴파일하지 않도록 해당 코드를 영구적으로 주석 처리합니다.

코더는 나중에 원할 경우 프로그램에서 해당 코드를 컴파일하도록 #ifdef를 변경할 수 있습니다.

코드가 존재하지 않는 것과 똑같습니다.


15

#if 0… #endif 블록은 정확히 무엇을합니까?

작성자가 버전 제어 시스템에 대해 들어 본 적이 없음을 알려줍니다. 그러면 가능한 한 멀리 달아 나라는 메시지가 표시됩니다.


12

#else케이스 에 추가하고 싶습니다 .

#if 0
   /* Code here will NOT be complied. */
#else
   /* Code will be compiled. */
#endif


#if 1
   /* Code will be complied. */
#else
   /* Code will NOT be compiled. */
#endif

7

전처리 기가 #을 볼 때 다음 토큰이 0이 아닌 값을 가지고 있는지 확인합니다. 그렇다면 컴파일러를위한 코드를 유지합니다. 그렇지 않은 경우 해당 코드를 제거하므로 컴파일러가 코드를 볼 수 없습니다.

누군가가 #if 0이라고 말하면 코드를 효과적으로 주석 처리하므로 컴파일되지 않습니다. 당신은 이것을 주변에 / * ... * /를 넣은 것처럼 생각할 수 있습니다. 동일하지는 않지만 효과는 동일합니다.

무슨 일이 일어 났는지 자세히 이해하고 싶다면 자주 볼 수 있습니다. 많은 컴파일러를 사용하면 전처리 기가 실행 된 후 파일을 볼 수 있습니다. 예를 들어 Visual C ++에서 switch / P 명령은 전처리기를 실행하고 결과를 .i 파일에 저장합니다.


좀 빠지는. 전처리 기는 토큰이 아닌 행별로 구문 분석합니다. 귀하의 설명에 따르면 예를 들어 말할 수는 #if WIN32 || __CYGWIN__없지만 예상대로 작동합니다.
Ben Voigt

나는 단순화하고 있었다. or가 있으면 토큰이 0이 아닌지 확인합니다. 마찬가지로가 있으면 둘 다 0이 아닌지 확인합니다.
Steve Rowe

3

a #로 시작하는 행 은 전 처리기 지시문 입니다. #if 0 [...] #endif블록은 컴파일러에 전달되지 않으며 기계어 코드를 생성하지 않습니다.

소스 파일을 사용하여 전처리 기가 어떻게되는지 보여줄 수 있습니다 ifdef.cxx.

#if 0
This code will not be compiled
#else
int i = 0;
#endif

실행 gcc -E ifdef.cxx하면 컴파일되는 내용이 표시됩니다.

이 메커니즘을 사용하여 개발주기 동안 코드 블록이 컴파일되는 것을 방지 할 수 있지만 소스 제어에 체크인하는 것을 원하지 않을 것입니다. 코드가 복잡해지고 가독성이 떨어질뿐입니다. 주석 처리 된 코드의 역사적 조각이라면 제거해야합니다. 소스 제어에는 기록이 포함되어 있습니다.

또한 대답은 CC ++ 모두 동일 할 수 있지만 C / C ++라는 언어가 없으며 이러한 언어를 참조하는 것은 좋은 습관이 아닙니다.


4
C / C ++를 "C 또는 C ++"의 약어로 말하는 것이 잘못된 이유는 무엇입니까? 솔직히 누군가 "C / C ++"라는 언어가 있다는 생각에 혼란 스러울 것이라고 생각하십니까?
Christopher Barber

1
@Chris : 사람들은 "어떻게 C / C ++에서 X를 수행합니까?"와 같은 질문을합니다. 말도 안되는 질문입니다. 당신은 둘 중 하나를 코딩하고 있으며 아직 선택하지 않았다면 그 사실을 명시해야합니다. 그래서, 예, 사람들은 "C / C ++"라는 언어가 있다는 것에 대해 혼란스러워합니다
Dennis Zickefoose

1
무의미한 말이군요! 답변이 C 및 C ++ 모두와 관련된 수천 개의 질문이 있습니다. 이것은 질문을하는 사이트라는 것을 기억하십시오. 일반적인 질문을한다고해서 사용중인 언어를 모른다는 의미는 아닙니다. 이 질문에서와 같이 이것이 사실이라고 의심되는 경우 C 또는 C ++를 지정하는 것이 어떻게 도움이됩니까? C 또는 C ++에 적용 할 수있는 모든 질문을 두 번 묻는 것이 도움이 될 것이라고 생각하십니까?
Christopher Barber

@Christopher : 맞습니다. 답변이 C, C ++ 및 Objective-C와 똑같이 관련된 질문이 많이 있습니다 (이 중 하나입니다). Stack Overflow에는 질문이 속한 언어를 나타내는 편리한 태깅 시스템이 있습니다. @Dennis가 언급했듯이 SO (및 기타 프로그래밍 포럼 [fora?])에는 C / C ++로 이러한 언어를 상호 교환 적으로 참조하는 C와 다른 C 파생 언어 사이의 묘사에 대해 혼동하는 사람들이 너무 많습니다. 적절한 언어로 질문에 답하기가 더 어렵습니다.
Johnsyweb

2

좀 빠지는

int main(void)
{
   #if 0
     the apostrophe ' causes a warning
   #endif
   return 0;
}

gcc 4.2.4에서 "tc : 4 : 19 : warning : missing terminating 'character"를 표시합니다.


2
이 경고는 컴파일러가 아닌 전처리기에 의해 생성됩니다. 컴파일러는 다음을 볼 수만 있습니다. # 1 "tc"# 1 "<built-in>"# 1 "<command-line>"# 1 "tc"int main (void) {return 0; }
Johnsyweb

0

주석 처리하는 저렴한 방법이지만 디버깅 가능성이 있다고 생각합니다. 예를 들어 파일에 값을 출력하는 빌드가 있다고 가정 해 보겠습니다. 최종 버전에서는 원하지 않을 수도 있으므로 #if 0 ... #endif를 사용할 수 있습니다.

또한 디버그 목적으로 수행하는 더 좋은 방법은 다음과 같습니다.

#ifdef DEBUG
// output to file
#endif

당신은 그와 같은 것을 할 수 있고 그것은 더 합리적 일 수 있고 당신이해야 할 일은 결과를보기 위해 DEBUG를 정의하는 것입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.