“false <true”작업이 올바르게 정의되어 있습니까?


153

C ++ 사양은 다음을 정의합니까?

  1. 부울 매개 변수에 대해 '보다 작음'연산자의 존재
  2. 4 개의 매개 변수 순열의 결과?

즉, 다음 작업의 결과가 사양에 정의되어 있습니까?

false < false
false < true
true < false
true < true

내 설정 (Centos 7, gcc 4.8.2)에서 아래 코드는 내가 기대하는 것을 뱉어냅니다 (C가 C를 사용하여 false를 0으로, true를 1로 표시 한 경우).

false < false = false
false < true = true
true < false = false
true < true = false

나는 대부분의 (모든?) 컴파일러가 동일한 출력을 줄 것이라고 확신하지만, 이것이 C ++ 사양에 의해 제정되어 있습니까? 또는 난독 처리가되었지만 사양 호환 컴파일러에서 true가 false보다 작다고 결정할 수 있습니까?

#include <iostream>

const char * s(bool a)
{
  return (a ? "true" : "false");
}

void test(bool a, bool b)
{
  std::cout << s(a) << " < " << s(b) << " = " << s(a < b) << std::endl;
}

int main(int argc, char* argv[])
{
  test(false, false);
  test(false, true);
  test(true, false);
  test(true, true);
  return 0;
}

6
@Ulterior 유효한 용도가 있습니다. 이러한 사용으로 std::minstd::vector<bool>&&.
Angew는 더 이상

19
아직에 StackOverflow의 모든 년 후 요청되지 않은 좋은 질문을 알아낼 수 있다면 @Ulterior, 당신은 자격이 몇 가지 포인트를. 트롤링이 아닙니다.
Mark Ransom

35
@Ulterior 묻는 동기는 진실입니다. 저는 C ++에 익숙하지 않고 (C에서 온) std :: set <>에 일부 객체를 저장하려고합니다. 내 객체의 <연산자 구현은 주로 객체의 부울 속성을 기반으로하며 다른 보조 식별 속성을 기반으로합니다. 세트를 반복 할 때 'false'객체가 먼저 나오는지 확인하고 싶습니다. 여기와 지금 저에게 효과적이지만, 내 객체의 < 운영자.
던컨

26
교란 결과는 즉 p <= q수단 p implies qpqbool 형식의있다!
Theodore Norvell

4
@Technophile 아마도 무슨 일이 그가됩니다 방해있어 <=실수로 LEFTARROW과 같이, 그 수도 우측으로 향하는 화살표가 때때로 또는 비공식적으로 유사하게 작성 조판한다 (즉, "[물질적]에서 알 수 있듯이") "에만" =>(A 두 배 샤프트 닮은, 즉 =) . 왼쪽 화살표는 때때로 "if"로 읽히지 만 "if if"에 오른쪽 화살표를 사용하는 것보다 훨씬 덜 일반적이라고 생각합니다.
Eliah Kagan

답변:


207

TL; DR :

작업은 C ++ 표준 초안에 따라 잘 정의되어 있습니다.

세부

우리는로 이동하여 그것을 볼 수 있습니다 표준 ++ 초안 C 섹션 5.9 관계 연산자 (라고 강조 광산 향후 ) :

피연산자는 산술 가져야한다 , 열거 또는 포인터 유형 , 또는 형식 표준 : nullptr_t합니다. 연산자 <(보다 작음),> (보다 큼), <= (보다 작거나 같음) 및> = (보다 크거나 같음)은 모두 거짓 또는 참입니다. 결과의 유형은 부울입니다

부울은 3.9.1 기초 유형의 산술 유형입니다.

유형 에서 bool , 문자, char16_t, char32_t, wchar_t를, 그리고 서명 및 부호없는 정수 유형은 공동으로하는 통합 유형을했다.

정수 및 부동 유형을 통칭하여 산술 유형이라고합니다.

truefalse에서 부울 리터럴 2.14.6부울 리터럴 :

boolean-literal:
    false
    true

5.9관계 연산자의 역학을 더보기 위해 섹션 으로 돌아가서 다음과 같이 말합니다.

일반적인 산술 변환은 산술 또는 열거 유형의 피연산자에서 수행됩니다.

일반적인 산술 변환이 섹션에 설명되어 있습니다 5밝히는 :

그렇지 않으면 적분 프로모션 (4.5)이 두 피연산자 모두에서 수행됩니다.

섹션 4.5은 말합니다 :

bool 유형의 prvalue는 int 유형의 prvalue로 변환 될 수 있으며, false는 0이되고 true는 1이됩니다.

그래서 표현은 :

false < false
false < true
true < false
true < true

이 규칙을 사용하면 다음과 같습니다.

0 < 0
0 < 1
1 < 0
1 < 1

6
좋아, 그것은 대답이 가능한 한 명시 적이지만 여전히 읽기 쉽습니다. nit : 잘못된 "type"을 굵게했다고 생각합니다. " 피연산자에는 산술 , 열거 또는 포인터 유형 또는 std :: nullptr_t 유형이 있어야합니다." 명확성을 위해 괄호를 추가하면 ((산술, 열거 또는 포인터) 유형) 또는 (std :: nullptr_t 유형)이 제공됩니다.

답이 바뀌지는 않지만 N3485 [over.built] / 12 : 승격 된 산술 유형 L 및 R의 모든 쌍에 대해 ... bool operator <(L, R); -당신이 인용 한 규칙이 적용되기 전에 선전 된 주장이 적용되지 않습니까?
chris

@ chris 나는 그 섹션에 익숙하지 않기 때문에 그것에 대해 생각해야하지만 대답이 내가 볼 수있는 것과 다르다고 생각하지 않습니다.
Shafik Yaghmour

예, 프로모션은 어느 쪽이든 먼저 발생합니다.
chris

63

와 부울 값은 보통의 정수 프로모션이 적용됩니다 false로 정의 0하고 true정의 1. 모든 비교가 잘 정의되어 있습니다.


2
... 관계형 연산자는 산술 또는 열거 유형의 피연산자에서 일반적인 산술 변환 (정수 승격 포함)을 수행하도록 지정됩니다.
TC

5
이 대답은 Shafik의보다 짧은 것을 좋아 I,하지만 중요한 점 생각 false으로 정의 0true같이 정의된다 1 표준에서 (오히려 단지 일반적인 관행보다는)을 백업하는 증거를 필요로합니다.
KRyan

@ KRyan 무엇을, 당신은 그것에 대한 내 말을하지 않을거야? :) bool형식이 있기 전에 C ++조차도 부울 연산의 결과는 0false와 1true 로 정의되었습니다 . K + R에서 찾을 수 있다면 놀라지 않을 것입니다.
Mark Ransom

1
@KRyan 나는 K + R까지는 되돌아 갈 수 없지만 1990 ANSI C 표준 사본을 파헤 쳤다. 섹션 6.3.8 각 연산자 "말한다 <(이하), >(이상) <=(이하 또는 동등 이하) 및 >=그이면 (보다 크거나 같음) 지정된 관계가 참이면 1을 수득한다 0 false입니다. 결과의 유형은 int"입니다."
Mark Ransom

1
IIRC의 가장 큰 문제는 K & R에서 enum bool { false = 0, true = 1}합법적이지만 정의하지 않았다는 것 operator<입니다.
MSalters

22

C ++ 표준 (5.9 관계 연산자)에 따름

2 일반적인 산술 변환은 산술 또는 열거 유형의 피연산자에서 수행됩니다.

1 ... 결과의 유형은 부울입니다.

(3.9.1 기본 유형)

6 bool 유형의 값은 true 또는 false입니다 .49 [참고 : 부호있는, 부호없는, 짧은 또는 긴 bool 유형 또는 값은 없습니다. — 끝 주] bool 유형의 값은 통합 프로모션 (4.5)에 참여 합니다.

(4.5 통합 프로모션)

6 bool 유형의 prvalue는 int 유형의 prvalue로 변환 될 수 있으며, false는 0이되고 true는 1이 됩니다.

따라서 모든 예제에서 true는 int 1로 변환되고 false는 int 0으로 변환됩니다

이 표현들

false < false
false < true
true < false
true < true

전적으로

0 < 0
0 < 1
1 < 0
1 < 1

8

부울 false은에 해당 int 0하고 부울 true은에 해당합니다 int 1. 그래서 이것은 false < true== 식 0 < 1만이를 반환하는 유일한 이유를 설명 합니다 true.

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