1. 비트필드 연산이란?
비트 필드 연산이란, 하나의 변수안에서도 그 안의 내용을 비트단위로 쪼개서 쓸 수 있는 연산이다.
#include <stdio.h>
#include <stdint.h>
union UNIO{
uint8_t data;
struct {
uint8_t a: 1;
uint8_t b: 2;
uint8_t c: 5;
};
} u1;
int main(){
u1.data = 87;
printf("a: %u\n", u1.a);
printf("b: %u\n", u1.b);
printf("c: %u\n", u1.c);
}
DEC: 87
BIN
최종 DEC 결과값
c, b, a 순으로 쪼개진다.
2. 만약 비트수가 선언된 타입의 크기를 넘어간다면?
그런데, 다음과 같이 비트를 넘어가는 순간, 오류가 발생한다.
#pragma pack(1)
#include <stdio.h>
#include <stdint.h>
union UNIO{
uint16_t data;
struct {
uint8_t a: 3;
uint8_t b: 2;
uint8_t c: 5;
};
} u1;
int main(){
u1.data = 87;
printf("a: %u\n", u1.a);
printf("b: %u\n", u1.b);
printf("c: %u\n", u1.c);
return 0;
}
DEC: 87
우리가 생각하는 BIN 구조
최종 DEC 결과값
하지만 이번엔 c 가 0이 나와버렸다!!
3. 왜 이런 현상이 발생하는가?
처음엔 이유를 찾는라 한참을 해맸지만, 곧 Eclipse로 메모리를 조회하며 이유를 알 수 있었다.
u1.c 의 주소지가 1밀려있는걸 알 수 있다.
따라서 실제 메모리 구조는 아래와 같은걸 알 수 있다.
실제 BIN 구조
4. 결과 / 주의점
결과적으로 Eclipse C 에서는 비트필드 연산자가 uint8_t 와 같이 앞에 선언된 변수의 할당 크기를 넘어가면, 다음 주소지로 변수를 밀어버린다는 것을 알 수 있다.
5. 그런데!!
반드시 꼭 밀어버리는 것도 아닌듯 하다..
Windows10 Eclipse (MinGW): 7, 2, 0
Ubuntu Gcc: 7, 2, 2
즉, Ubuntu Gcc에서는 우리가 예상했던 BIN 값이 나왔다.
이에 대한 이유와 설명은 다음 포스팅에서 다루어 보도록 하겠다.. (왜지..?)
'SSAFY' 카테고리의 다른 글
[SSAFY 임베디드 C] int 암시적 형변환 (2) | 2024.09.28 |
---|---|
[SSAFY 12기 합격 후기] 준비 과정 및 꿀팁! (전공) (0) | 2024.06.19 |