부울 연산자 ++ 및- 뒤에 어떤 이유가 있습니까? 이것은 다음을 컴파일합니다. static

오늘 Visual C ++ 코드를 작성하는 동안 저를 놀라게 한 무언가를 발견했습니다. C ++는 bool에 대해 ++ (증가)를 지원하지만-(감소)는 지원하지 않는 것 같습니다. 이것은 단지 임의의 결정일 뿐입니 까, 아니면 그 뒤에 어떤 이유가 있습니까?

이것은 다음을 컴파일합니다.

static HMODULE hMod = NULL;
static bool once = false;
if (!once++)
    hMod = LoadLibrary("xxx");

이것은하지 않습니다 :

static HMODULE hMod = NULL;
static bool once = true;
if (once--)
    hMod = LoadLibrary("xxx");


답변

정수 값을 부울로 사용한 역사에서 비롯됩니다.

경우 x입니다 int,하지만 난에 따라 부울로 사용하고 if(x)...다음 작업을하기 전에 그 무엇이든 그것의 진리 값을 의미합니다 증가, 그것의 진리 값 것이다 true뒤에 (오버 플로우를 금지 참조).

그러나 (적분 값이 1 인 경우) 또는 (적분 값이 다른 경우-특히 여기에는 0 [ ] 및 2가 포함됨 ) 결과가 발생할 수 있으므로 --의 진리 값에 대해서만 주어진 지식 의 결과를 예측하는 것은 불가능합니다. 더 [xfalsetruefalsetrue ]).

그래서 짧은 손으로 ++일했으며,-- 가 있었지만 그렇지 않았습니다.

++ 이것과의 호환성을 위해 bools에서 허용되지만 표준에서는 더 이상 사용되지 않습니다.


이것은 내가 부울 로만 사용 한다고 가정합니다. 즉 x, ++자체적으로 오버플로를 일으킬만큼 자주 수행 할 때까지 오버플로가 발생할 수 없습니다 . char을 사용하는 유형으로 CHAR_BITS5와 같이 낮은 값을 사용하더라도 더 이상 작동하지 않는 32 배입니다 (아직도 나쁜 습관 이기에 충분한 논쟁입니다. 나는 연습을 방어하는 것이 아니라 작동하는 이유 만 설명합니다) 32 비트 int의 경우 당연히 ++이것이 문제가되기 전에 2 ^ 32 번 사용해야 합니다. 에 대해 1의 값으로 시작하거나 0으로 시작하여 정확히 한 번 사용 --false경우 에만 결과가 나타 납니다 .true++

0보다 약간 낮은 값으로 시작하는 경우에는 다릅니다. 실제로 이러한 경우 다음 과 같은 값을 최종적 ++으로 얻을 수 있습니다 false.

int x = -5;
while(++x)
  doSomething(x);

그러나,이 예를 취급 x하여 AS int조건을 제외한 모든 곳은, 그래서 동등입니다 :

int x = -5;
while(++x != 0)
  doSomething(x);

x부울 로만 사용하는 것과 다릅니다 .


답변

ANSI ISO IEC 14882 2003 (c ++ 03) :

5.2.6-2

postfix의 피연산자-피연산자가 bool 유형이 아니라는 점을 제외하면 postfix ++ 연산자와 유사하게 감소합니다. [참고 : 접두사 증가 및 감소에 대해서는 5.3.2를 참조하십시오. ]

그리고 당연히 …

5.3.2-2

접두사의 피연산자-1을 빼서 수정합니다. 피연산자는 bool 유형이 아니어야합니다. 접두사의 피연산자에 대한 요구 사항과 그 결과의 속성은 그렇지 않으면 접두사 ++의 요구 사항과 동일합니다. [참고 : 후위 증가 및 감소에 대해서는 5.2.6을 참조하십시오. ]

또한 5.6.2-1 및 5.3.2-1에서는 ++ for bool이 참이어야한다고 언급하고 Annex D-1에서는 ++ on bool이 더 이상 사용되지 않는다고 말합니다.


답변

역사적 이유 때문에 이것이 지원되었습니다. 그러나
++ 연산자와 함께 bool 유형의 피연산자를 사용하는 것은 더 이상 사용되지 않습니다. C ++ 표준 (n3092)의 섹션 5.3.2를 참조하십시오.

5.3.2 증가 및 감소 [expr.pre.incr]

  • 접두사 ++의 피연산자는 1을 추가하여 수정하거나 bool이면 true로 설정합니다 (이 사용은 더 이상 사용되지 않음). 피연산자는 수정 가능한 lvalue 여야합니다. 피연산자의 유형은 산술 유형이거나 완전히 정의 된 객체 유형에 대한 포인터 여야합니다. 결과는 업데이트 된 피연산자입니다. lvalue이고 피연산자가 비트 필드 인 경우 비트 필드입니다. x가 bool 유형이 아닌 경우 표현식 ++ x는 x + = 1과 같습니다 [참고 : 변환에 대한 정보는 더하기 (5.7) 및 할당 연산자 (5.17)에 대한 설명을 참조하십시오. —end note]
  • 접두사의 피연산자-1을 빼서 수정합니다. 피연산자는 bool 유형이 아니어야합니다. 접두사의 피연산자에 대한 요구 사항과 그 결과의 속성은 그렇지 않으면 접두사 ++의 요구 사항과 동일합니다.

답변

  • 이전 표준 (C ++ 98)에서는 오류가 아닙니다.
  • 새로운 표준이 증가함에 따라 부울은 더 이상 사용되지 않습니다. (C ++ 11)
  • C ++ 17까지 부울에 증분을 사용할 수 있습니다.