지시문 매크로 비교 main() {

#if다음 코드 의 조건이 충족되는 이유는 무엇입니까?

#include <iostream>
#define VALUE foo    

int main() {    
#if VALUE == bar
    std::cout << "WORKS!" << std::endl;
#endif // VALUE
}



답변

cppreference.com페이지는 다음과 같이 말합니다.

정의 된 __has_include (C ++ 17 이후) 표현식의 모든 매크로 확장 및 평가 후에 부울 리터럴이 아닌 모든 식별자는 숫자 0으로 대체됩니다 (이에는 어휘 키워드이지만, ).

모두 지금 foobar0으로 대체됩니다.


답변

A의 #if문 (제외한 매크로 교체 후 남아있는 식별자 truefalse) 상수로 대체된다 0. 그래서 당신의 지시는

#if 0 == 0

뭐가 진실이지.


답변

이는 정의 나 값이 제공 foo되지 않았기 때문에 bar동일하므로 (즉, “0”값으로 대체 됨). 컴파일러는 이에 대해 경고합니다.

MSVC(2019 스튜디오 시각) 컴파일러는 다음을 제공합니다 :

경고 C4668 : ‘# if / # elif’에 대해 ‘foo’가 전 처리기 매크로로 정의되지 않아 ‘0’으로 대체됩니다
. 경고 C4668 : ‘bar’가 ‘#if에 대해’0 ‘으로 대체되는 전 처리기 매크로로 정의되지 않았습니다. / # elif ‘

따라서 VALUE값은 ‘0’(기본값은 foo)이며 bar‘0’도 있으므로 VALUE == bar“TRUE”로 평가됩니다.

마찬가지로 clang-cl다음을 제공합니다.

경고 : ‘foo’가 정의되지 않았고 0으로 평가됨 [-Wundef]
경고 : ‘bar’가 정의되지 않았습니다. 0으로 평가됩니다 [-Wundef]


답변

당신이 무엇을했는지 달성하려면 다음을 시도하십시오.

#include <iostream>
#define DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

이 경우 “define”을 “undef”로 변경하여 디버깅 명령문을 끌 수 있습니다.

#include <iostream>
#undef DEBUG  

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

컴파일러를 사용하면 코드 외부에서 DEBUG를 정의 할 수 있으며이 시점에서 코드를

#include <iostream>

int main() {    
#ifdef DEBUG
    std::cout << "WORKS!" << std::endl;
#endif
}

그런 다음 -DDEBUG = 0과 같은 옵션으로 컴파일러를 호출하십시오.

Steve McConnell의 수비 프로그래밍, “코드 완료”장을 확인하십시오.


답변