C ++ struct 구문 "A : B"는 무엇을 의미합니까?
-
05-07-2019 - |
문제
C ++ struct가있는 경우 64 비트 데이터 단어를 정의합니다.
struct SMyDataWord
{
int Name : 40;
int Colour : 24;
};
무엇을합니까 : 40
구문은 ... 처음 40 비트가 이름과 나머지 24 비트를 위해 예약되어 있음을 의미합니까?
이것이 사용되는 방식이지만 전에는 접근하지 못했습니다.
해결책
C에서 이월 된 비트 필드 Name
너비는 40 비트이며 Colour
폭 24 비트입니다. 따라서 구조물에는 64 비트 이상이 있습니다. 내 시스템에서 64 비트는 8 바이트입니다.
다른 팁
예, 그것은 구문입니다 비트 필드. 그들은 일반적으로 하드웨어 레지스터에 매핑되는 스트러크를 정의하는 데 사용됩니다. 사용하기로 결정한 경우 명심해야 할 사항이 있습니다. 하나는 필드를 구성하는 실제 바이트에서 컴파일러가 어떻게 레이아웃, 주문 및 패딩을 수행하는지 알 수 없다는 것입니다. 동일한 컴파일러이지만 최적화 설정이 다릅니다).
그것은 비트 필드 정의입니다.
이름은 정확히 40 비트의 정보를 저장할 수있는 정수입니다. 색상은 24 비트를 저장할 수 있습니다.
이것은 종종 필요한 구조물로 일부 공간을 절약하거나 CPU에 대해 쉽게 처리 할 수있는 크기로 코드를 압축하기 위해 수행됩니다 (귀하의 경우 64 비트. 64 비트 기계의 CPU 레지스터에 정확히 맞습니다).
비트 필드에 액세스하는 코드는 약간 느리게 실행됩니다.
비트 필드에 관한 거의 모든 것이 구현에 따라 다릅니다. 예를 들어, 비트가 왼쪽에서 오른쪽으로 저장되는지 또는 오른쪽에서 왼쪽에서 오른쪽으로 저장되는지 여부는 실제 하드웨어 아키텍처에 따라 다릅니다. 또한 각 컴파일러는 다른 멤버 정렬 모델을 사용하므로 최적화 된 BillingRec의 크기는 9가 아닌 12 바이트입니다. 비트 필드의 주소를 가져갈 수 없거나 비트 배열을 만들 수 없습니다. 마지막으로, 대부분의 구현에서 비트 필드의 사용은 속도 오버 헤드가 발생합니다. 따라서 코드를 최적화 할 때 코드를 사용하기 전에 특정 최적화와 그 트레이드 오프의 효과를 측정하십시오.
여기 sizeof
후드 아래에서 무슨 일이 일어나고 있는지 잘 보여줍니다.
#include <iostream>
#include <climits>
struct bc_1 {
int a : 1;
int b : 1;
};
struct bc_2 {
int a : 31;
int b : 1;
};
struct bc_3 {
int a : 32;
int b : 1;
};
struct bc_4 {
int a : 31;
int b : 2;
};
struct bc_5 {
int a : 32;
int b : 32;
};
struct bc_6 {
int a : 40;
int b : 32;
};
struct bc_7 {
int a : 63;
int b : 1;
};
int main(int argc, char * argv[]) {
std::cout << "CHAR_BIT = " << CHAR_BIT;
std::cout << " => sizeof(int) = " << sizeof(int) << std::endl;
std::cout << "1, 1: " << sizeof(struct bc_1) << std::endl;
std::cout << "31, 1: " << sizeof(struct bc_2) << std::endl;
std::cout << "32, 1: " << sizeof(struct bc_3) << std::endl;
std::cout << "31, 2: " << sizeof(struct bc_4) << std::endl;
std::cout << "32, 32: " << sizeof(struct bc_5) << std::endl;
std::cout << "40, 32: " << sizeof(struct bc_6) << std::endl;
std::cout << "63, 1: " << sizeof(struct bc_7) << std::endl;
}
다음은 컴파일러 및 OS 및 하드웨어에 따라 다릅니다. GCC-7이있는 MACOS에서 (a CHAR_BIT
= 8, 32 비트 int
(즉, 64 비트의 절반 long
) 가지다 sizeof(int)
= 4) 이것은 내가 본 출력입니다.
CHAR_BIT = 8 => sizeof(int) = 4
1, 1: 4
31, 1: 4
32, 1: 8
31, 2: 8
32, 32: 8
40, 32: 12
63, 1: 8
이것은 우리에게 몇 가지를 알려줍니다. int
유형은 단일에 맞습니다 int
(위의 예에서 32 비트), 컴파일러는 단일 만 할당됩니다. int
기억의 가치 (bc_1
그리고 bc_2
). 한 번, 싱글 int
더 이상 비트 필드를 붙잡을 수없고 두 번째를 추가합니다 (bc_3
그리고 bc_4
). 주목하십시오 bc_5
용량이 있습니다.
흥미롭게도, 우리는 허용보다 더 많은 비트를 "선택"할 수 있습니다. 보다 bc_6
. 여기서 G ++ -7은 경고를합니다.
bitfields.cpp::30:13: warning: width of 'bc_6::a' exceeds its type
int a : 40;
^~
참고 : Clang ++는 이것을 더 자세히 설명합니다.
bitfields.cpp:30:9: warning: width of bit-field 'a' (40 bits) exceeds the width of its type; value will be truncated to 32 bits [-Wbitfield-width]
int a : 40;
^
그러나 후드 아래에서 컴파일러가 다른 사람을 할당하는 것 같습니다. int
기억의 가치. 또는 최소한 올바른 크기를 결정합니다. 컴파일러 가이 메모리에 액세스하지 말라고 경고하는 것 같습니다. int a = bc_6::a
(나는 그것을 베팅 할 것이다 int a
그런 다음 처음 32 비트의 필드 만 있으면됩니다. bc_6::a
...). 이것은 확인됩니다 bc_7
총 크기는 두 가지입니다 int
S, 그러나 첫 번째 필드는 대부분을 다룹니다.
마지막으로 교체 int
~와 함께 long
위의 예에서 예상대로 작동합니다.
CHAR_BIT = 8 => sizeof(long) = 8
1, 1: 8
31, 1: 8
32, 1: 8
31, 2: 8
32, 32: 8
40, 32: 16
63, 1: 8