programing

FALSE와 TRUE의 이상한 정의, 왜?

goodsources 2023. 11. 2. 21:40
반응형

FALSE와 TRUE의 이상한 정의, 왜?

제가 작업하고 있는 어떤 코드에서 저는 진실과 거짓에 대한 이상한 재정의를 발견했습니다.저는 수표를 좀 더 엄격하게 하기 위해 그런 것들을 본 적이 있지만, 제 마음에는 이 일이 좀 이상해서 누가 그런 정의를 내리는 데 적절한 이유가 무엇인지 말해줄 수 있는지 궁금합니다. 그 옆에 제 의견이 있는 아래를 참조하십시오.

#define FALSE (1 != 1) // why not just define it as "false" or "0"?
#define TRUE (!FALSE)  // why not just define it as "true" or "1"?

이 코드베이스에는 이상한 특이점들이 많이 있습니다.모든 표준 유형에 대해 다음과 같은 재정의가 있는 것과 같습니다.

#define myUInt32 unsigned integer // why not just use uint32_t from stdint?

이 모든 작은 별난 소리들은 제가 무언가 명백한 것을 놓치고 있는 것처럼 느끼게 해주지만, 저는 정말 요점을 알 수가 없습니다.

참고: 엄밀하게는 c++ 코드이지만 'c' 프로젝트에서 포팅된 것일 수도 있습니다.

휴대성이 목적인 것 같습니다.

#define FALSE (1 != 1) // why not just define it as "false" or "0"?
#define TRUE (!FALSE)  // why not just define it as "true" or "1"?

이들은 이를 지원하는 언어(C++)에서 부울 형식을 사용하는 반면 그렇지 않은 언어에서는 여전히 사용 가능한 숫자 값을 제공합니다(명시적 부울 데이터 형식을 사용했음에도 불구하고 C - C99 및 C11까지 포함).

부울을 가능한 곳에 두는 것이 기능 과부하에 좋습니다.

#define myUInt32 unsigned integer // why not just use uint32_t from stdint?

좋아요.stdint를 사용할 수 있습니다.여러분은 그런 것들을 당연하게 생각할지도 모르지만, 세상은 넓고 넓습니다!이 코드는 그것을 인식합니다.

면책 사항:개인적으로, 저는 표준을 고수하고 1990년 이후에 출시된 컴파일러가 필수 조건임을 간단히 언급하고자 합니다.하지만 우리는 해당 프로젝트의 기본 요구사항이 무엇인지 모릅니다.

TRWTF는 문제가 된 코드의 작성자가 이에 대해 나란히 논평을 통해 설명하지 않았다는 것입니다.

#define FALSE (1 != 1) // why not just define it as "false" or "0"?

제가 생각하기에는 표현의 종류가(1!=1)부울 값에 대한 언어 지원에 따라 다릅니다. C++인 경우 유형은bool, 그렇지 않으면int.

반면에0항상 입니다int, 두 언어로, 그리고falseC에서는 인식되지 않습니다.

엄밀하게는 c++ 코드이지만 'c' 프로젝트에서 포팅된 것일 수도 있습니다.

이것은 앞서 언급한 것처럼 휴대성에 관한 것이지만, 실제로는 훨씬 이상입니다.언어를 준수하기 위해 언어 정의를 교묘하게 이용하는 것입니다.

이 황당해 보이는 매크로들은 언뜻 보기에는 그렇게 황당하지 않지만, 사실은 C와 C++ 모두에게 다음과 같은 것을 보장하기 때문에 기발합니다.TRUE그리고.FALSE의 값(및 유형)이 정확합니다.true그리고.false(비록 컴파일러가 그런 키워드가 없는 C 컴파일러라 할지라도, 당신은 사소한 것으로 다음과 같은 것을 쓸 수 없습니다.#define TRUE true).

C++ 코드에서는 언어가 정의하기 때문에 이러한 구문은 쓸모가 없을 것입니다.true그리고.false키워드로.
그러나 C와 C++가 동일한 코드 기반에서 원활하게 상호 운용되도록 하려면 (다른 코드 스타일을 사용하지 않는 한) 둘 다에 적합한 "something"이 필요합니다.

이 매크로가 정의되는 방식은 C++ 표준이 어떤 값인지에 대해 명확하게 모호하다는 것을 증명하는 것입니다.true그리고.false실제로 가지고 있습니다.C++ 표준은 다음과 같습니다.

유형 boole의 값이 true 또는 false입니다.
[...]
0 값, null 포인터 값 또는 null 멤버 포인터 값은 false로 변환되며, 다른 값은 true로 변환됩니다.
[...]
유형 bool의 prvalue를 유형 int의 prvalue로 변환할 수 있으며 false는 0이 되고 true는 1이 됩니다.

두 개의 특정 값이 존재하고 이름이 무엇인지, 그리고 이 값들이 어떤 정수 값으로 변환되고 어떤 정수 값에서 변환되는지는 언급하지 않지만 이러한 값이 무엇인지는 언급하지 않습니다.당신은 그 가치들이 분명히0그리고.1(그리고 부수적으로 당신은 옳을 것이라고 추측했을지도 모릅니다) 하지만 사실은 그렇지 않습니다.실제 값은 의도적으로 정의되지 않습니다.

이는 포인터(특히 널 포인터)가 정의되는 방식과 유사합니다.0의 정수 리터럴은 널 포인터로 변환되고 널 포인터는false, 동일한 것을 비교합니다...허허허 허허허허허...등.
어떤 것이 무엇으로 변환되고 무엇이 되지 않는지에 대해서는 많은 이야기가 있지만, 널 포인터가 0의 이진법을 가져야 한다는 은 어디에도 언급되지 않습니다. (사실은 그렇지 않은 몇몇 이국적인 구조들이 있습니다!)

C에서 마이그레이션된 오래된 코드, 표준이 아닌 C++ 컴파일러의 코드, 크로스 컴파일러 코드(휴대성), 하위 호환성을 지원하기 위한 코드 스타일, 나쁜 습관 등의 역사적인 이유가 있습니다.

몇몇 컴파일러들이 있었는데 그들은 아직<cstdint>같은 정수형의 경우uint32_t, 아니면 그들은 하지 않았습니다.<cstdbool>. 훌륭한 프로그래머는 자신의 프로그램이 여러 컴파일러에 걸쳐 잘 정의되도록 하기 위해 모든 것을 정의하고 사전 프로세서를 많이 사용해야 했습니다.

오늘은 저희가.<cstdint>,true/false,<cstdbool>, 모두가 행복합니다!

이 정의의 좋은 점은 TRUE 또는 FALSE에서 정수로의 암묵적 변환을 피하는 것입니다.이것은 컴파일러가 잘못된 함수 오버로드를 선택하지 않도록 하는 데 유용합니다.

C에는 네이티브 부울 타입이 없었기 때문에 다른 곳에서 "false" 또는 "true"를 정의하지 않고는 엄격하게 사용할 수 없었습니다. 그러면 어떻게 정의하시겠습니까?

같은 주장이 나에게 적용됩니다.UInt32 - C는 원래 uint32_t 및 stdint의 다른 유형을 가지고 있지 않았기 때문에 정확한 크기의 정수를 얻을 수 있습니다.다른 아키텍처로 포팅한 경우에는 다음과 같은 정의를 변경하면 됩니다.UInt32는 부호 없는 정수 32비트 너비와 동일한 길이 또는 짧은 길이입니다.

FALSE와 FALSE의 차이를 설명하는 멋진 설명이 있습니다.대부분의 답변이 설명을 해주긴 했지만 조금 더 이해하는데 도움이 될 수도 있을 것 같습니다. 여기.

언급URL : https://stackoverflow.com/questions/19359381/strange-definition-of-false-and-true-why

반응형