C ++ : bool이 8 비트 인 이유는 무엇입니까?


132

C ++에서 부울 유형이 8 비트 길이 (내 시스템에서) 왜 부울 값을 보유하기에 충분합니까?

나는 그것이 성능상의 이유라고 생각했지만 레지스터가 32 또는 64 비트 너비 인 32 비트 또는 64 비트 시스템에서 성능 이점은 무엇입니까?

아니면 이러한 '역사적'이유 중 하나입니까?


9
bool은 시스템에서 8 비트가 아닙니다. int와 같은 4 바이트입니다.
Brian Neal

21
마지막으로 누군가가 당신의 생각을 생각했을 때, 우리는 std :: vector <bool>로 끝났습니다. 가장 싫어하는 stl "기능"=)
Viktor Sehr

1
jldupont, 당신이 나를 잘못 읽은 것 같아요. 나는 sizeof(bool)4가 될 시스템을 요구하고 있었다. 나는 msvc가 32 비트 bool을 가지고 있다고 맹세 할 수 있지만 방금 시도했지만 그렇게하지 않았다.
avakar

7
공평하게 말해서, 문제 vector<bool>는 그것이 영리하고 부울을 비트로 묶는 것이 아니라 STL 컨테이너로 위장 하려고한다는 것 입니다. 평범한 비트 셋은 STL 컨테이너 인 척하지 않는 한 좋을 것입니다.
jalf

2
@avakar-C ++ bool데이터 유형을 BOOLtypedef로 정의 된 Windows 유형 과 혼동 할 수 있습니다 long. 그래서 sizeof(bool) != sizeof(BOOL), 나는 많은 혼란 (그리고 아마도 많은 수의 버그)을 일으킬 것이라고 확신합니다. 특히 Windows 에는 boolean및에 BOOLEAN대한 별칭 인 typedef 가 있기 때문 입니다 unsigned char. 또한 bool1 바이트 인 것이 일반적이지만 C ++ 표준에는 sizeof(bool)더 클 수 있음을 나타내는 메모가 있습니다.
Michael Burr

답변:


219

모든 C ++ 데이터 유형은 주소 지정이 가능해야하기 때문입니다.

단일 비트에 대한 포인터를 어떻게 작성 하시겠습니까? 당신은 할 수 없습니다. 그러나 바이트에 대한 포인터를 만들 있습니다. 따라서 C ++의 부울은 일반적으로 바이트 크기입니다. (더 클 수도 있습니다. 구현에 달려 있습니다. 가장 중요한 것은 주소를 지정할 수 있어야하므로 C ++ 데이터 유형이 바이트보다 작을 수는 없습니다)


7
"바이트"주소 지정은 아키텍처 선택 (hw 수준)입니다. 다른 "주소 지정 단위"를 가진 시스템을 매우 잘 설계 할 수 있습니다. 일반적인 프로세서의 경우 "바이트"를 지정하면 외부 메모리에서 "바이트"이상을 가져 오는 결과가 발생합니다. 이는 효율성상의 이유 때문입니다.
jldupont

8
예, 하드웨어 선택이며 하드웨어가 허용하는 경우 bool의 크기가 변경 될 수 있습니다. 그러나 OP는 부울이 8 비트 너비 인 이유를 물었고 그 경우 시스템에서는 일반적으로 CPU가 8 비트 바이트 만 처리 할 수 ​​있기 때문입니다.
jalf

2
@jldupont : 포인터 주소가 바이트보다 세분화 된 몇 가지 시스템이 있지만 (이전의 TI TMS34010 / 20에서 비트 단위 포인터를 사용하여 프로그래밍 했음) 시스템은 거의 없습니다.
Michael Kohne

1
당신이 무슨 뜻인지 확실하지. 모든 객체는 주소를 지정할 수 있어야합니다. 즉, 객체의 주소를 검색 할 수 있어야합니다. 객체는 자체 주소를 저장할 필요가 없습니다. 문자는 일반적으로 8 비트이며 256자를 저장할 수있을만큼 충분하지만 각 문자는 메모리의 위치에 따라 주소가 정의됩니다. 그래서 char에 대한 포인터를 만들 수 있습니다.
jalf

88
내가 유쾌한 비유를 할 수 있다면 : 내 건물에는 8 층이 있지만 우체국은 그 주소가 다르다는 것을 인정하지 않습니다. 따라서 주소를 모두 원한다면 실제로 한 층에 맞더라도 건물 전체를 임대해야합니다. 나는 다른 7 층을 "주소 저장"을 사용하지 않고, 우체국 규칙으로 인해 층이 아닌 건물을 지칭하기 때문에 낭비해야합니다. C ++ 객체는 자신에게 주소를 가져야한다-배달 후 우편을 분류 할 포스트 룸이 없다 ;-)
Steve Jessop

39

메모리는 바이트 주소를 지정할 수 있습니다. 메모리에서 읽은 바이트를 이동하거나 마스킹하지 않으면 단일 비트를 처리 할 수 ​​없습니다. 이것이 매우 큰 이유라고 생각합니다.


1
항상 그런 것은 아닙니다. 8051 MCU는 예를 들면, 비트의 어드레스 가능 위치의 16 바이트를 갖는
올린

20

boolean유형은 일반적으로 어드레스 가능한 메모리의 최소 단위 이하 대상 기기 (즉, 일반적으로 8 비트 바이트)의이.

메모리에 대한 액세스는 항상 "청크"(여러 단어, 이는 하드웨어 수준 , 버스 트랜잭션 에서의 효율성을 위한 )입니다. 부울 비트는 대부분의 CPU 시스템에서 "단독"으로 처리 될 수 없습니다. 물론 일단 데이터가 레지스터에 포함되면 비트를 독립적으로 조작하는 특수 명령이 종종 있습니다.

이러한 이유로 "부울"기본 데이터 유형을 사용할 때 효율성을 높이기 위해 "비트 패킹" 기술을 사용하는 것이 일반적 입니다. enum2 코딩의 거듭 제곱을 갖는 (C에서)와 같은 기술 이 좋은 예입니다. 대부분의 언어에서 같은 종류의 속임수가 있습니다.

업데이트 : 훌륭한 토론 덕분 에 C ++의 정의 에 따라 주목을 sizeof(char)==1받았습니다 . 따라서 "부울"데이터 형식의 주소 지정은 주소 지정 가능한 메모리의 가장 작은 단위와 밀접한 관련이 있습니다 (내 요점을 강화).


이것에 관해 당신이 남긴 모든 의견들에 대해, 당신은 대답의 가장 중요한 부분 bool을 빠뜨린 것이 인상적입니다 : C ++은 포인터를 생성 할 수 있어야하기 때문에 타입은 할당 가능한 메모리의 가장 작은 단위를 따릅니다 . 이 요구 사항이 없으면 bool현재 바이트 주소 지정 가능 컴퓨터에서도 a가 단일 비트로 표시 될 수 있습니다.
jalf

1
흠 ... 나는 약간의 주소를 지정할 수있는 CPU 아키텍처를 만들 수 있습니다 ... 심지어 컴파일러 등을 작성할 수도 있습니다. "비트 주소 지정 가능"할 수있는 특별한 메모리 영역 (또는 무엇이든)을 가질 수 있습니다. 상상할 수없는 것은 아닙니다.
jldupont

2
예, 그리고 그 시스템에서 부울은 단일 비트로 만들 수 있습니다. 그러나 OP는 "왜 가상의 CPU에서 8 비트 폭의 부울 이냐"고 묻지 않았다. 그는 현재의 일반적인 CPU에 대해 물었고 바이트 주소를 지정할 수 있기 때문입니다.
jalf

4
C ++에서 정의 당 sizeof (char) == 1이므로 하드웨어가 할 수 있거나 할 수없는 것은 관련이 없습니다. sizeof (bool) <sizeof (char)를 가질 수 없습니다. BTW C ++는 가장 작은 하드웨어 주소 지정 가능 장치를 char로 설정하는 것이 편리하지 않은 경우 하드웨어가 처리 할 수있는 것의 일부 하위 장치를 처리하는 "지방"포인터를 가질 수있는 방식으로 정의됩니다. 이것은 오래된 워드 주소 지정 가능 아키텍처를 위해 적어도 일부 C 컴파일러에서 사용되었습니다.
AProgrammer

@AProgrammer : sizeof(char)==1 definition: 그건 내 주장에 대한 반론이다. 감사!
jldupont

6

주소를 지정할 수있는 가장 작은 메모리 양인 8 비트에 대한 답변이 맞습니다. 그러나 일부 언어 부울에 1 비트를 사용할 있습니다. Pascal 구현 세트를 비트 문자열로 기억하는 것 같습니다. 즉, 다음 세트의 경우 :

{1, 2, 5, 7}

이것을 메모리에 가지고있을 수 있습니다 :

01100101

물론 C / C ++에서 비슷한 것을 할 수 있습니다. (당신이 논리 값의 무리를 추적하는 경우, 그것은 이해,하지만 정말 상황에 따라 달라집니다.)


8
실제로 C ++은 특수 컨테이너 벡터 <bool>를 사용하여이 작업을 수행합니다. 일반적으로 재난으로 간주됩니다.

C ++은 C에서 상속 된 "비트 필드"를 사용하여이를 수행합니다. struct / class의 멤버 변수를 선언 할 때 값을 저장하는 데 사용되는 비트 수를 선언 할 수 있습니다 (예 : "부호없는 짧은 필드 : 3").

@ 닐 : 왜 재난으로 여겨지 는가? 성능 문제입니까?
Jérôme

2
@Jerome : 비트를 처리 할 수 ​​없기 때문에 일반처럼 작동 할 수 없기 때문 vector입니다. 동작에 제약이 있기 때문에 실제로는 STL 유형 컨테이너가 아닙니다. 더 나쁜 것은 누군가를 가지고 있고 그것을 bool만들고 싶어하는 누군가에게 문제를 일으킨다 vector는 것입니다. 그것은 놀라운 행동이며 언어에서 원하는 것이 아닙니다.
David Thornley

1
@jldupont-이와 같은 요점을 한 번 작성하면 충분합니다. 그리고 C ++은 하드웨어가 무엇을 할 수 있든지 비트를 처리 할 수 ​​있다는 것을 보증하지 않습니다.

1

나는 이것이 오래되었다는 것을 알고 있지만 나는 2 센트를 던질 것이라고 생각했다.

부울 또는 데이터 형식을 1 비트로 제한하면 응용 프로그램에서 메모리가 손상 될 위험이 있습니다. 1 비트 길이의 메모리에서 오류 통계를 어떻게 처리합니까?

나는 면접에 갔고 프로그램 담당자가 나에게 말한 진술 중 하나는 "미사일 발사 신호를 보낼 때 무선을 통해 비트 하나에서 비트를 보내면된다. 한 비트를 보내는 것은 매우 빠르다. 그 신호를 가능한 빨리해야합니다. "

글쎄, 개념과 비트, 바이트 및 오류 처리를 이해했는지 확인하는 테스트였습니다. 나쁜 사람이 1 비트 메시지를 보내는 것이 얼마나 쉬운가요? 또는 전송 중에 비트가 다른 방향으로 뒤집 히면 어떻게됩니까?


질문 새로운 질문을 다른 질문에 대한 답변으로 질문을 게시하지 않습니다.
Igor Jerosimić

6
이 "답변"에 포함 된 질문은 실제로 수사적이라고 생각합니다. 즉, 우리가 부울을 1 비트로 구현하지 않는 이유는 단일 비트가 오류 통계를 처리 할 수 ​​없기 때문입니다.
Stephen Holt

1
@StephenHolt 그러나 그 이유는 아니며 TBH는이 대답이 의미가 없습니다.
doc

1
...뭐? CRC와 같은 또는 트랩 표현과 같은 "오류 통계"가 무엇을 의미하는지 모르겠습니다. 그러나 어떤 경우에도 더 큰 유형의 코드조차도 "오류 통계"에 여분의 "예비"비트를 사용하지 않습니다. 극한 환경의 코더는 코드가 메모리를 읽기 전에 하드웨어가 오류 감지 / 수정을 처리 할 수 ​​있다고 가정하기 때문입니다. 검증 정보 등으로 모든 변수를 채우는 데 시간을 소비 할 필요가 없습니다. bool다른 7 비트 또는 31 비트는 확실히 "오류 통계"에 사용 되지 않기 때문에 OP 머신에서 8 비트를 사용하고 광산에서 32 비트를 사용하는 이유 는 아닙니다. 이것은 말이되지 않습니다
underscore_d

1

일부 임베디드 컴파일러에는 부울 플래그를 비트 패킹하는 데 사용되는 int1 유형이 있습니다 (예 : Microchip MPU 용 CCS C 컴파일러 시리즈). 이러한 변수의 설정, 지우기 및 테스트는 단일 명령어 비트 수준 명령어를 사용하지만 컴파일러는 다른 답변에 언급 된 이유로 인해 다른 작업 (예 : 변수의 주소 사용)을 허용하지 않습니다.

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