source

왜 MACRO+0을 사용하는가!=0

goodcode 2022. 8. 27. 09:31
반응형

왜 MACRO+0을 사용하는가!=0

현재의 코드 베이스에서는, 다음의 패턴이 표시됩니다.

#if SOMETHING_SUPPORTED+0 != 0
...
#endif

유감스럽게도 이것은 매우 오래된 코드 베이스이며, 아무도 어떻게, 왜 시작되었는지 모릅니다.C에서 시작해서 수업과 함께 서서히 C로 바뀌어 지금은 C++로 바뀌는 경향이 있는 것 같습니다.

"클래식" 대신 이전 구문을 사용하는 것의 분명한 장점은 알 수 없지만, 뭔가 놓치고 있는 것 같습니다.

#if SOMETHING_SUPPORTED
...
#endif

왜 이런 걸 쓰는지 알아?#if MACRO+0 != 0대신#if MACRO?

여기서의 단서는 코드 베이스가 매우 오래되었다는 것입니다.

이 트릭은 미정의 매크로를 프리프로세서에서 0으로 취급하지 않는 매우 오래된 프리프로세서를 탑재한 컴파일러에 코드가 포팅되었기 때문에 존재할 가능성이 있습니다.#if조건.

즉, 1989년 ANSI C에서 다음과 같은 기능이 있는 경우 표준화되었습니다.

#foo + bar - xyzzy

명령어는 매크로 치환의 대상이 되기 때문에foo,bar또는xyzzy매크로로 치환됩니다.교체되지 않은 나머지 식별자는 다음으로 대체됩니다.0그래서 만약에foo로 정의됩니다.42,그렇지만bar그리고.xyzzy정의되어 있지 않습니다.

#if 42 + 0 - 0

예를 들어 잘못된 구문은 아닙니다.

#if 42 + -

또는 진단과 같은 다른 동작도 있습니다.bar정의되지 않았습니다.

정의되지 않은 매크로가 공백으로 처리되는 프리프로세서에서는#if SOMETHING_SUPPORTED확장하여#if이 경우 오류가 발생합니다.

이 방법밖에 없어IDENT+0속임수는 정말 말이 돼요ISO C 준거 전처리에 의존할 수 있다면 이 작업은 결코 하고 싶지 않을 것입니다.

그 이유는 만약SOMETHING_SUPPORTED에는 숫자 값이 필요합니다.단순히 공백으로 정의하기 위해 잘못 산란됩니다.이상적으로는 이 문제가 발생한 시기를 검출하고 진단을 통해 컴파일을 중지하는 것이 좋습니다.

두 번째로, 이러한 산란 브레인 사용을 지원하는 경우, 명시적으로 정의되어 있지만 공백인 기호가 값 0이 아닌 값 1인 것처럼 동작하는 것이 거의 확실합니다.그렇지 않으면 함정을 만드는 거야컴파일러 명령줄에서 다음을 수행할 수 있습니다.

 -DSOMETHING_SUPPORTED=$SHELL_VAR  # oops, SHELL_VAR expanded to nothing

또는 코드:

 #define SOMETHING_SUPPORTED  /* oops, forgot "1" */

아무도 추가하지 않을 것이다.#define또는-D제어하는 기능을 끌 목적으로 기호를 선택합니다.를 삽입하는 프로그래머#define SOMETHING_SUPPORTED를 제외하고1행동에 놀라다

 #if SOMETHING_SUPPORTED+0

활성화해야 할 재료를 건너뜁니다.

이 때문에, 이것을 읽고 있는 C프로그래머는 거의 그러한 사용법을 본 적이 없다고 생각됩니다.또, 이것은, 블록의 건너뛰기를 의도한 프리프로세서 동작의 회피책이라고 생각되는 이유입니다.SOMETHING_SUPPORTED가 없습니다.「프로그래머의 함정」이 놓여 있는 것은, 회피책의 부작용에 지나지 않습니다.

프로그래머 트랩을 작성하지 않고 이러한 프리프로세서의 문제를 해결하려면 변환 유닛의 초기 단계에서 다음과 같은 것이 필요합니다.

#ifndef SOMETHING_SUPPORTED
#define SOMETHING_SUPPORTED 0
#endif

그리고 다른 곳에서는 그냥#if SOMETHING_SUPPORTED원래 프로그래머에게 그런 접근법이 떠오르지 않았을 수도 있고, 아니면 그 프로그래머가 그렇게 생각했을 수도 있습니다.+0트릭은 깔끔하고 자기 계발에 가치를 둔다.

#if X+0 != 0와는 다르다#if X의 경우Xempty로 정의되어 있습니다(주의: 이것은, 다음의 경우와 다릅니다).X정의되지 않음) 예:

#define X

#if X          // error
#if X+0 != 0   // no error; test fails

빈 매크로를 정의하는 것은 매우 일반적입니다.프로젝트 구성에서는 여러 행을 포함하는 공통 헤더가 생성될 수 있습니다.#define USE_FOO,#define USE_BAR시스템이 지원하는 기능을 활성화하는 등의 작업을 수행합니다.

!= 0중복되는 코드입니다.#if X+0.


이렇게 ㅇㅇㅇㅇㅇㅇ를 은,#if X+0, 만약 약 is is is is isX이 경우 에러를 트리거하는 대신 블록을 건너뛰고 컴파일을 계속합니다.

의 여지가 저는 으로 이 말을 쓰겠습니다.개인적으로는#ifdef는, 「」등입니다.USE_SOME_FEATURE , , , , 입니다.#if들어 일 수 의 경우.또, 실수로 「」를 사용했을 는, 에러가 됩니다.#if비우도록 정의된 무언가를 가지고 있습니다.

식탁을 만들자!

X       #if X     #if X+0 != 0
<undef> false     false
<empty> error     false
0       false     false
1       true      true
2       true      true
a       false     false
xyz     false     false
12a     error     error
12 a    error     error

따라서 (코멘터 덕분에) 유일한 차이점은 X가 정의되어 있지만 값이 없는 경우(빈 문자열 등)입니다. 영화예요+0 != 0를 참조해 주세요.

그것은 또 다른 글쓰기 방법이다.

 #if defined(MACRO) && MACRO != 0

+0은 결과가 숫자임을 확인하기 위해 사용됩니다. ifMACRO있지 . 구문 오류를 피할 수 있습니다.이것에 의해 발생하는 구문 오류를 회피합니다.#if MACRO != 0.

질이 안 좋은 물건이지만, 꼭 해야 할 일이 아니면 건드리지 마세요.

언급URL : https://stackoverflow.com/questions/37048006/why-would-one-use-macro0-0

반응형