C ++의 부울 유형이 ++를 지원하지만-를 지원하지 않는 이유는 무엇입니까?


29

왜 연산자 --는 bool에 존재 하지 않고 연산자 는 bool에 존재 ++합니까?

C ++로 시도했지만 내 질문이 다른 언어에 적용되는지 알 수 없습니다. 나는 또한 알게되어 기쁘다.

나는++ bool과 함께 연산자 를 사용할 수 있다는 것을 알고있다 . 부울을 true로 만듭니다.

bool b = false;
b++;
// Now b == true.

왜 연산자 --를 반대 방향으로 사용할 수 없습니까?

bool b = true;
b--;
// Now b == false;

그다지 유용하지는 않지만 궁금합니다.


8
StackOverflow에 대한이 질문은 깨달을 수 있습니다.
Blrfl

그래서 역사 이유. 링크 주셔서 감사합니다. 답을 쓸 수 있고 해결 된대로 넣을 수 있습니까?
aloisdg는 Reinstate Monica가

링크만으로는 좋은 답변을 얻지 못하고 다른 SE 사이트에 문제의 사본을 표시하는 좋은 메커니즘이 없습니다.
Blrfl

1
따라서 meta.stackexchange.com 또는 어떤 주제로 주제를 열어야합니다. 나는 당신이 좋은 링크를 위해 업장을 얻어야한다고 생각합니다. 누군가 당신을 찬성한다면, 원래의 대답에서 저자는 업장을 얻어야합니다. 사실, 원래 질문은 업장도 얻어야합니다.
aloisdg는

2
@aloisdg 크로스 사이트 딥은 MSO 의 오래된 문제 입니다. 전체 질문 을 보려면 링크 된 질문 을 추적하십시오 .

답변:


53

C의 옛날에는 부울 유형이 없었습니다. 사람들은 int부울 데이터를 저장하기 위해를 사용 했으며 대부분 작동했습니다. 0은 거짓 이었고 다른 모든 것은 사실이었습니다.

이것은 당신이 int flag = 0;나중에 가져 가면 flag++가치가 사실 이라는 것을 의미했습니다 . 이것은 플래그 값이 무엇이든 관계없이 작동 합니다 (많이하지 않으면 롤오버하고 0으로 돌아 왔지만 무시할 수 있습니다) -값이 1 일 때 플래그를 늘리면 2가됩니다. 참된.

어떤 사람들은 이것을 무조건 부울 값을 true로 설정하기 위해 사용했습니다. 나는 그것이 관용어 가 된 것이 확실하지 않지만 일부 코드 에서는 확실하지 않습니다 .

이를 위해 일한 적이 --값이 (가 할 수있는) 1 이외 인 경우, 값은 여전히 거짓되지 않을 것 때문에. 그리고 이미 거짓 ( 0)이고 감소 연산자를 사용했다면 거짓으로 유지되지 않습니다.

초기에 C에서 C ++로 코드를 옮길 때 C ++에 포함 된 C 코드가 여전히 작동 할 수 있어야했습니다. 따라서 C ++ 사양 (섹션 5.2.6 (페이지 71))에서 다음과 같이 읽습니다.

접미사 ++를 적용하여 얻은 값은 연산자를 적용하기 전에 피연산자가 가진 값입니다. [참고 : 획득 한 값은 원래 값의 사본입니다.] 피연산자는 수정 가능한 lvalue 여야합니다. 피연산자의 유형은 산술 유형이거나 완전한 객체 유형에 대한 포인터입니다. 결과가 표시된 후, 오브젝트 유형이 아닌 경우 오브젝트 값이 1로 추가되면 오브젝트 값이 1로 추가되어 오브젝트 값이 수정됩니다 bool. [참고 :이 사용은 더 이상 사용되지 않습니다. 부록 D 참조]

postfix의 피연산자는 피연산자가 유형이 아닌 것을 제외하고 postfix ++ 연산자와 유사하게 감소합니다 bool.

이것은 섹션 5.3.2에서 다시 언급됩니다 (접두사 연산자의 경우-5.2.6은 접미사에 있음).

보시다시피, 이것은 더 이상 사용되지 않으며 (문서의 부록 D, 709 페이지) 사용해서는 안됩니다.

그러나 그 이유입니다. 때로는 코드가 표시 될 수도 있습니다. 하지만하지 마십시오.


5
"어떤 사람들은 이것을 무조건 부울 값을 true로 설정하기 위해 사용했습니다." 사람들이 아니라 그들을 바보라고 부르 자.
중복 제거기

@Deduplicator : 성능 문제 일 수 있습니다. 변수에 값을로드하면 변수를 증가시키는 것보다 더 많은 프로세서주기가 소요될 수 있습니다. 물론 이것은 현대 컴퓨터에서는 중요하지 않습니다.
Giorgio

1
@Giorgio는 가능성이 높습니다. C는 PDP-7 명령어 세트와 거의 일치하도록 작성되었으며 PDP-11에는 다른 조정이있었습니다. 에서 - "사람들은 종종 그들이 년 12 PDP-11 C와 유닉스가 처음 인기가있는가 제공하는 자동 증가 및 자동 감소 주소 모드를 사용하기 위해 만들어졌습니다 추측이 역사적으로 불가능하다, 더 PDP- 없었다 때문이다. 그러나 PDP-7은 몇 개의 '자동 증가'메모리 셀을 가지고 있었으며,이를 통해 간접 메모리 참조는 셀을 증가 시켰다는 특성을 가지고있다.

@ 중복 제거기 : 부울에 정수를 사용하는 코드에서 각각에 대해 증가하는 변수 ... 무엇이든 ... 카운터 (증분 횟수)와 부울 (모두 증가했거나 아니).
Keith Thompson


1

이 질문의 역사적 중요성을 이해하려면 Therac-25의 경우를 고려해야합니다. Therac-25는 암 환자에게 방사선을 전달하는 의료 기기였습니다. 안전하지 못한 기록을 세운 나쁜 프로그래밍 관행에 시달렸습니다 (여러 명의 사망자가 원인).

http://courses.cs.vt.edu/professionalism/Therac_25/Therac_1.html

(3 페이지 하단으로 이동)

설정 테스트 루틴을 통과 할 때마다 Class3이라는 공유 변수 인 상위 콜리메이터 위치 점검이 증가합니다. Class3이 0이 아닌 경우 불일치가 있으며 치료를 진행해서는 안됩니다. Class3의 값이 0이면 관련 매개 변수가 처리와 일치하며 빔이 억제되지 않음을 나타냅니다.

...

기계 설정 중에 설정 이벤트는 다른 이벤트가 발생할 때까지 대기하기 때문에 수백 번 실행됩니다. 이 코드에서 Class3 변수는 설정 테스트를 통과 할 때마다 하나씩 증가합니다. Class3 변수는 1 바이트이므로 최대 값은 255 자입니다. 따라서 256 번째 설정 테스트 코드를 통과 할 때마다 변수가 오버플로되고 값이 0이됩니다. 즉, 설정 테스트를 통해 매 256 번째 단계마다 상위 콜리메이터가 확인되지 않고 상위 콜리메이터 오류가 감지되지 않습니다. 과다 노출은 Class3가 0으로 롤오버 된 순간에 작업자가 "설정"버튼을 눌렀을 때 발생했습니다. 따라서 Chkcol이 실행되지 않았고 F $ mal은 상단 콜리메이터가 여전히 필드 라이트 위치에 있음을 나타내도록 설정되지 않았습니다. 대상이없고 스캔하지 않고 소프트웨어가 전체 25 MeV를 켰습니다. 매우 집중된 전자빔이 생성되었고, 이는 경로에있는 스테인레스 스틸 거울에 의해 흩어지고 편향되었다.

Therac-25는 operator++on 과 같은 것을 사용 했습니다 bool. 그러나 그들이 사용한 프로그래밍 언어는 C ++이 아니었고 데이터 유형은 아니 었습니다 bool. 그러나 C ++의 보장과 달리 일반 정수 유형은 계속 증가합니다. 그들의 데이터 유형은에 해당 uint8_t합니다.

C ++은 operator++이와 같은 프로그래밍에 익숙한 사람들 을 위해 주변 을 지키기로 결정 했지만 값을 늘리는 대신 true이와 같은 것을 막기 위해 단순히 설정합니다 .

참고 operator++(bool)되지 않습니다.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2013/n3797.pdf

C ++ 14의 부록 D :

D.1 bool 피연산자가
있는 증가 연산자 ++ 연산자와 함께 bool 유형의 피연산자는 더 이상 사용되지 않습니다 (5.3.2 및 5.2.6 참조).


그것이 더 이상 사용되지 않는 이유를 설명하지만 처음에 왜 존재하는지 설명하지는 않습니다.

C로 프로그래밍 할 때 값을 증가시켜 부울 값을 설정하는 사람들이 있었기 때문에 존재합니다. C ++은 C에서 쉽게 전환 할 수 있도록 설계되었으므로 bool유형으로 지원했습니다 . 사람들이 실제로 이런 식으로 프로그래밍 한 경우에 대한 역사적인 예를 제공하려고했습니다.
David Stone
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.