[C/C++] 구조체 bitfield 멤버 변수 선언 ( ':' )
[*] tcmalloc 코드를 분석하다가 Span 구조체의 멤버 변수 선언부에 `:`으로 신기하게 변수가 선언된 부분이 있어서 찾아보다가 알게된 bitfield에 대해 정리해봤따.
[*] bitfield?
C/C++ 구조체에 있는 문법으로 특정 변수의 크기를 비트 단위로 정할 때 사용한다.
struct {
unsigned int a : 16;
unsigned int b : 16;
unsigned short c;
} typedef test;
위와 같이 선언한다면 a와 b 변수는 원래는 4바이트의 크기를 갖는 unsigned int 형이지만 16비트로 크기 제한을 걸었기
때문에 실제로는 2바이트의 크기만을 갖게 된다. (근데 타입은 유지함..)
이 경우 a와 b 변수는 unsigned short int 형으로 변환된다.
비트 단위는 2^n 단위로 설정할 수 있다.
[*] 사용 목적
struct {
unsigned int a : 2;
unsigned int b : 1;
} typedef test;
예를 들어 2비트 또는 1비트만 필요한 변수라면 위와 같이 선언하여 메모리 낭비를 최소로 만들 수 있다. (극한의 효율...)
[*] 테스트 코드
// unsigned int refcount : 16; 이런 문법 테스트
#include <stdio.h>
#include <stdlib.h>
#define type(x) _Generic((x), \
_Bool: "_Bool", unsigned char: "unsigned char", \
char: "char", signed char: "signed char", \
short int: "short int", unsigned short int: "unsigned short int", \
int: "int", unsigned int: "unsigned int", \
long int: "long int", unsigned long int: "unsigned long int", \
long long int: "long long int", unsigned long long int: "unsigned long long int", \
float: "float", double: "double", \
long double: "long double", char *: "char *", \
void *: "void *", int *: "int *", \
default: "unknown")
struct {
unsigned int a : 16;
unsigned int b : 16;
unsigned short c;
} typedef test;
struct {
unsigned int a : 16;
unsigned short c;
unsigned int b : 16;
} typedef test2;
struct {
unsigned short c;
unsigned int a : 16;
unsigned int b : 16;
} typedef test3;
int main(){
test *buf = malloc(sizeof(test));
test2 *buf2 = malloc(sizeof(test2));
test3 *buf3 = malloc(sizeof(test3));
buf->a = 0x1111;
buf->b = 0x2222;
buf->c = 0x3333;
buf2->a = 0x1111;
buf2->b = 0x2222;
buf2->c = 0x3333;
buf3->a = 0x1111;
buf3->b = 0x2222;
buf3->c = 0x3333;
// break point
printf("value : %p, type : %s\n", buf->a, type(buf->a));
return 0;
}
oz1ng@LAPTOP-6F0C4A2N:/mnt/c/Users/ghdxo/Desktop/oz1ng_Lab/tcmalloc/test$ ./colon_test
value : 0x1111, type : unsigned short int
[*] 메모리 확인
pwndbg> x/20gx 0x405290
0x405290: 0x0000000000000000 0x0000000000000021
0x4052a0: 0x0000333322221111 0x0000000000000000
0x4052b0: 0x0000000000000000 0x0000000000000021
0x4052c0: 0x0000222233331111 0x0000000000000000
0x4052d0: 0x0000000000000000 0x0000000000000021
0x4052e0: 0x0000222211113333 0x0000000000000000
0x4052f0: 0x0000000000000000 0x0000000000020d11
0x405300: 0x0000000000000000 0x0000000000000000
0x405310: 0x0000000000000000 0x0000000000000000
0x405320: 0x0000000000000000 0x0000000000000000
테스트 코드에서 break point 부분까지 실행 후 buf, buf2, buf3의 값을 확인한 모습이다.
unsigned int형이지만 실제로는 unsigned short int와 똑같이 작동하는 것을 볼 수 있다.
[*] 주의
- sizeof의 인자로 비트 필드 변수는 들어갈 수 없다.
[*] 참고
- https://stackoverflow.com/questions/4706584/what-does-this-mean-in-c-int-a16
what does this mean in c int a:16;?
Possible Duplicate: What does 'unsigned temp:3' mean? please what does this notation mean int a:16; I found it is code like this and it does compile. struct name { int ...
stackoverflow.com