programing

MACRO + 0! = 0을 사용하는 이유

nasanasas 2020. 10. 26. 08:04
반응형

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에서 다음과 같이 표준화되었습니다.

#if foo + bar-xyzzy

지시어는 경우 그래서, 매크로 교체 대상이다 foo, bar또는 xyzzy매크로를, 그들은이 대체됩니다. 그런 다음 대체되지 않은 나머지 식별자는로 대체됩니다 0. 그래서 경우 foo로 정의 42하지만, barxyzzy모두에 정의되어 있지 않은, 우리가 얻을 :

#if 42 + 0 - 0

그리고 잘못된 구문이 아닙니다.

#if 42 + -

또는 bar정의되지 않은 것에 대한 진단과 같은 다른 동작 .

정의되지 않은 매크로가 공백으로 처리되는 전 처리기에서 #if SOMETHING_SUPPORTEDjust로 확장되면 #if오류가 발생합니다.

IDENT+0이것이이 트릭이 실제로 의미 가있는 유일한 방법입니다 . ISO C를 준수하는 전처리에 의존 할 수 있다면이 작업을 절대 원하지 않을 것입니다.

그 이유는에 SOMETHING_SUPPORTED숫자 값이있을 것으로 예상 되는 경우 단순히 공백으로 정의하는 것이 잘못 분산되어 있기 때문입니다. 이상적으로 이런 일이 발생했을 때를 감지하고 진단을 통해 컴파일을 중지하는 것이 좋습니다.

당신이 경우 둘째, 어떻게 그런 침착하지 못한 사용을 지원, 당신은 거의 확실히의 값이 1이 아닌 값 0 그렇지 않으면, 당신은 함정을 만드는을 가진 것처럼 명시 적으로 정의하지만, 빈 기호 행동을합니다. 누군가 컴파일러 명령 줄에서이 작업을 수행 할 수 있습니다.

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

또는 코드에서 :

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

아무도하려고하지 않습니다 추가#define하거나 -D회전의 의도와 상징에 대한 오프 가 제어하는 기능을! #define SOMETHING_SUPPORTED없이 a를 삽입하는 프로그래머 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경우 X비워 정의된다 (참고 :이 경우에 다른 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경우이다 X빈 다음 편집으로 정의 된 블록의 존재는 건너 뛰고 대신 오류를 트리거의 계속.

Whether this is a good idea is debatable, personally I would use #ifdef for boolean macros like USE_SOME_FEATURE, and #if for macros where the value might be a range of integers for example; and I would want to see an error if I accidentally use #if with something defined to empty.


Let's make a table!

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

So the only difference we've found (thanks to commenters) is the case where X is defined but has no value (like empty string). I've never seen the +0 != 0 variant before.


It's another way of writing

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

The +0 is there to ensure the result is a number. If MACRO isn't defined it avoids the syntax error that would result from #if MACRO != 0.

Poor quality stuff, but don't mess with it unless you gotta.

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

반응형