programing

단순하게 1이 아닌 C 부울 매크로에서 #sublic TRUE(1==1)를 사용하는 이유는 무엇입니까?

coolbiz 2022. 7. 7. 23:48
반응형

단순하게 1이 아닌 C 부울 매크로에서 #sublic TRUE(1==1)를 사용하는 이유는 무엇입니까?

C의 정의를 본 적이 있다.

#define TRUE (1==1)
#define FALSE (!TRUE)

이거 필요해?TRUE를 1로, FALSE를 0으로 단순하게 정의하면 어떤 이점이 있습니까?

이 접근방식에서는, 실제의 데이터를 사용합니다.boolean입력(및 해결)true그리고.false컴파일러가 지원하는 경우(구체적으로는 C++)

단, C++가 사용 중인지 여부를 확인하는 것이 좋습니다.__cplusplus매크로) 및 실제 사용true그리고.false.

C 컴파일러에서 이것은 다음과 같습니다.0그리고.1.
(동작 순서에 따라 괄호를 삭제하면 괄호가 깨집니다)

정답은 휴대성입니다.의 수치TRUE그리고.FALSE중요하지 않아요.중요한 것은 다음과 같은 진술입니다.if (1 < 2)까지 평가하다.if (TRUE)그리고 다음과 같은 진술이 있습니다.if (1 > 2)까지 평가하다.if (FALSE).

인정합니다(C).(1 < 2)까지 평가하다.1그리고.(1 > 2)까지 평가하다.0그래서 컴파일러에 관한 한 실제적인 차이는 없습니다.하지만 컴파일러에 의해TRUE그리고.FALSE그 자체의 규칙에 따라 프로그래머에게 그 의미를 명확히 하고 프로그램과 다른 라이브러리 내에서 일관성을 보장한다(다른 라이브러리가 C 표준을 따르는 경우...놀라실 거예요.)


일부 이력
일부 기본 정의FALSE~하듯이0그리고.TRUE~하듯이-1많은 현대 언어들과 마찬가지로, 그들은 0이 아닌 어떤 값도 다음과 같이 해석했다.TRUE, 다음과 같은 부울식을 평가했습니다.-1.그들의.NOT연산은 1을 더하고 기호를 뒤집는 방식으로 수행되었습니다. 왜냐하면 그렇게 하는 것이 효율적이기 때문입니다.그래서 'NOT x'는-(x+1)이것의 부작용은 다음과 같은 가치가 있다는 것입니다.5까지 평가하다.TRUE,그렇지만NOT 5까지 평가하다.-6이 또한TRUE이런 종류의 버그를 찾는 것은 즐겁지 않다.

베스트 프랙티스
사실상의 규칙들을 고려할 때 0은 다음과 같이 해석됩니다.FALSE0이 아닌 값은 다음과 같이 해석됩니다.TRUE부울처럼 보이는 표현은 또는 와 비교하지 마십시오.예:

if (thisValue == FALSE)  // Don't do this!
if (thatValue == TRUE)   // Or this!
if (otherValue != TRUE)  // Whatever you do, don't do this!

왜냐고요? 왜냐하면 많은 프로그래머들이 치료의 지름길을 이용하기 때문입니다.int로서bools. 동일하지는 않지만 일반적으로 컴파일러가 허용하고 있습니다.그래서 예를 들어, 이 글을 쓰는 것은 완전히 합법적이다.

if (strcmp(yourString, myString) == TRUE)  // Wrong!!!

그것은 정당해 보이고 컴파일러는 기꺼이 받아들일 것입니다만, 아마 당신이 원하는 대로 되지 않을 것입니다.그 이유는 의 수익률이기 때문이다.strcmp()

0의 경우yourString == myString
0 미만인 경우yourString < myString
0을 넘는 경우yourString > myString

그래서 위의 라인이 반환됩니다.TRUE할 때만yourString > myString.

올바른 방법은 다음 중 하나입니다.

// Valid, but still treats int as bool.
if (strcmp(yourString, myString))

또는

// Better: lingustically clear, compiler will optimize.
if (strcmp(yourString, myString) != 0)

마찬가지로:

if (someBoolValue == FALSE)     // Redundant.
if (!someBoolValue)             // Better.
return (x > 0) ? TRUE : FALSE;  // You're fired.
return (x > 0);                 // Simpler, clearer, correct.
if (ptr == NULL)                // Perfect: compares pointers.
if (!ptr)                       // Sleazy, but short and valid.
if (ptr == FALSE)               // Whatisthisidonteven.

이러한 「나쁜 예」를 실가동 코드에서 자주 볼 수 있습니다.많은 경험 많은 프로그래머는, 이러한 예에 대해 맹세합니다.이 예들은 기능하고, 일부는 올바른 대체 예보다 짧으며, 관용구는 거의 보편적으로 인식되고 있습니다.그러나 "올바른" 버전은 효율이 떨어지고 휴대성이 보장되며 아무리 엄격한 라인터라도 통과할 수 있으며 새로운 프로그래머도 이를 이해할 수 있습니다.

그만한 가치가 있지 않나요?

(1 == 1)트릭을 정의하는데 도움이 됩니다.TRUEC에는 투명하지만 C++에는 더 나은 입력을 제공합니다.Clean C(C 또는 C++로 컴파일)라는 사투리로 쓰거나 C 또는 C++ 프로그래머가 사용할 수 있는 API 헤더 파일을 쓰는 경우에도 동일한 코드가 C 또는 C++로 해석될 수 있습니다.

C번역단위에서는1 == 1와 정확히 같은 의미를 가지다1; 및1 == 0와 같은 의미를 가지다0단, C++ 번역 유닛에서는1 == 1타입이 있다bool그래서...TRUEC++에 더 잘 통합될 수 있도록 정의된 매크로입니다.

통합이 더 잘 되는 방법의 예로는 예를 들어 기능이foo에 대한 과부하가 있다int및 을 위해bool,그리고나서foo(TRUE)를 선택합니다.bool과부하한다면TRUE라고 정의되어 있을 뿐입니다.1C++에서는 잘 동작하지 않습니다. foo(TRUE)원하는 것은int과부하

물론 C99는bool,true,그리고.falseC99 및 C에서 작동하는 헤더 파일에서 사용할 수 있습니다.

단,

  • 정의하는 이 관행TRUE그리고.FALSE~하듯이(0==0)그리고.(1==0)C99보다 이전 버전입니다.
  • C99를 멀리하고 C90으로 작업해야 할 좋은 이유가 여전히 있습니다.

C와 C++가 혼합된 프로젝트에서 작업 중이고 C99를 원하지 않는 경우 소문자를 정의합니다.true,false그리고.bool대신.

#ifndef __cplusplus
typedef int bool;
#define true (0==0)
#define false (!true)
#endif

말하자면0==0트릭은 C++와 상호 운용할 의도가 전혀 없는 코드에서도 일부 프로그래머에 의해 사용되었습니다.그것은 아무것도 사지 않고 프로그래머가 C에서 부울란이 어떻게 동작하는지에 대해 오해하고 있음을 시사한다.


C++에 대한 설명이 명확하지 않은 경우 테스트 프로그램을 다음에 제시합니다.

#include <cstdio>

void foo(bool x)
{
   std::puts("bool");  
}

void foo(int x)
{
   std::puts("int");  
}

int main()
{
   foo(1 == 1);
   foo(1);
   return 0;
}

출력:

bool
int

C와 C++가 혼합된 프로그래밍과 관련하여 C++ 함수가 어떻게 과부하되는지에 대한 코멘트로부터의 질문에 대하여.이것들은 단지 타입의 차이를 나타내고 있습니다.필요한 타당한 이유true constant to be bool when compiled as C++ is for clean diagnostics. At its highest warning levels, a C++ compiler might warn us about a conversion if we pass an integer as a bool parameter. One reason for writing in Clean C is not only that our code is more portable (since it is understood by C++ compilers, not only C compilers), but we can benefit from the diagnostic opinions of C++ compilers.

#define TRUE (1==1)
#define FALSE (!TRUE)

is equivalent to

#define TRUE  1
#define FALSE 0

in C.

The result of the relational operators is 0 or 1. 1==1 is guaranteed to be evaluated to 1 and !(1==1) is guaranteed to be evaluated to 0.

There is absolutely no reason to use the first form. Note that the first form is however not less efficient as on nearly all compilers a constant expression is evaluated at compile time rather than at run-time. This is allowed according to this rule:

(C99, 6.6p2) "A constant expression can be evaluated during translation rather than runtime, and accordingly may be used in any place that a constant may be."

PC-Lint will even issue a message (506, constant value boolean) if you don't use a literal for TRUE and FALSE macros:

For C, TRUE should be defined to be 1. However, other languages use quantities other than 1 so some programmers feel that !0 is playing it safe.

Also in C99, the stdbool.h definitions for boolean macros true and false directly use literals:

#define true   1
#define false  0

Aside from C++ (already mentioned), another benefit is for static analysis tools. The compiler will do away with any inefficiencies, but a static analyser can use its own abstract types to distinguish between comparison results and other integer types, so it knows implicitly that TRUE must be the result of a comparison and should not be assumed to be compatible with an integer.

Obviously C says that they are compatible, but you may choose to prohibit deliberate use of that feature to help highlight bugs -- for example, where somebody might have confuse & and &&, or they've bungled their operator precedence.

The pratical difference is none. 0 is evaluated to false and 1 is evaluated to true. The fact that you use a boolean expression (1 == 1) or 1, to define true,아무런 차이가 없다.둘 다 평가받고int.

C 표준 라이브러리는 부란을 정의하기 위한 특정 헤더를 제공합니다.stdbool.h.

TRUE의 정확한 값은 알 수 없으며 컴파일러마다 정의가 있을 수 있습니다.따라서 사용자가 원하는 것은 컴파일러의 내부 버전을 정의에 사용하는 것입니다.프로그래밍 습관은 좋지만 다음과 같은 일부 코딩 스타일의 문제를 방지할 수 있는 경우에는 이 방법이 항상 필요한 것은 아닙니다.

(a > b) == TRUE인 경우

TRUE의 내부 값이 다른 값인 반면 TRUE를 1로 정의하면 재해가 발생할 수 있습니다.

  1. 목록 항목

일반적으로 C 프로그래밍 언어에서는 1이 true로 정의되고 0이 false로 정의됩니다.따라서 다음 항목이 자주 표시됩니다.

#define TRUE 1 
#define FALSE 0

단, 0이 아닌 숫자는 조건문에서도 true로 평가됩니다.따라서 다음을 사용합니다.

#define TRUE (1==1)
#define FALSE (!TRUE)

거짓을 사실이 아닌 것과 동등하게 만들어서 안전하게 하려고 노력한다는 것을 분명히 보여줄 수 있습니다.

언급URL : https://stackoverflow.com/questions/17010041/why-define-true-1-1-in-a-c-boolean-macro-instead-of-simply-as-1

반응형