지시문 매크로 비교


25

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

#include <iostream>
#define VALUE foo    

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

답변:


26

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

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

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


C ++ 98, C ++ 03, C ++ 11 및 C ++ 14는 어떻습니까?
kelalaka

1
@kelalaka 모두 동일합니다. C89 이후로 그랬습니다.
SS Anne

1
@kelalaka "C ++ 17 이후"는 "and __has_include"부분만을 참조합니다. C ++ 17 이전에는 그 부분이 생략 된 것과 동일했습니다.
BessieTheCow

15

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

#if 0 == 0

뭐가 진실이지.


명확히하기 위해 '#define VALUE foo'는 'VALUE'기호를 정의하여 'foo'기호와 동일한 값으로 해석되지만 'foo'기호는 의미가 없으므로 0으로 해석됩니다.
ManicDee

14

이는 정의 나 값이 제공 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]


경고는 필수입니까 아니면 컴파일러의 기능입니까?
kelalaka

1
@kelalaka 내가 아는 한, 컴파일러 '경고'는 필수가 아닙니다! 심지어로 MSVCclang-cl컴파일러,이 경고는 (중 특히, 또는 적절한 경고 '수준'을 설정하여) 비활성화 할 수 있습니다.
Adrian Mole

0

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

#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의 수비 프로그래밍, "코드 완료"장을 확인하십시오.

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