C언어

[C 언어] 데이터 타입의 형 변환 (2)

Teodore 2023. 1. 20. 23:20
728x90

오늘은 데이터 형변환에 관련된 이야기를 추가로 해보려 한다. 

 

먼저 아래 코드를 보자. 

1
unsigned short val = -1;
cs

이것은 정상일까 에러일까?

정답은 정상코드이다. 개발자의 흔한 오해중 하나가 unsigned 라는 단어를 보면 음수는 절대로 들어갈 수 없다고 생각한다는 것이다. 사실 음수는 변환 과정이 필요한 것 뿐이지 별다른 의미를 품고 있지는 않다. (음수 변환 과정에 대해서는 2의 보수 방법(bit 반전 후 더하기 1) 참조)

따라서 위의 코드는 val에 0xFFFF가 담겨 있는 의미로 해석된다. 

 

그럼 아래 코드를 살펴보자

1
2
unsigned short val = -1;
signed short val2 = -1;
cs

val과 val2 모두 -1이 들어있다. 이 값은 같은가? 물론 2개의 값은 모두 0xFFFF로 같다. 

그렇다면 이제 아래의 문제를 풀어볼 차례다. 

1
2
3
4
5
6
7
8
9
10
11
int main(void){
    unsigned short val = -1;
    signed short val2 = -1;
    if(val == val2){
        printf("val == val2\n");
    }
    else{
        printf("val != val2\n");
    }
    return 0;
}    
cs

방금 val과 val2는 모두 0xFFFF값이라고 했으니 당연히 val == val2가 출력될 것 같지만, 눈치가 있는 사람이라면 다르다는 것을 알고 있을 것이다. 

그럼 왜 달라지는지 이유를 알아보자. 

 

지난 시간에 자동 형 변환되는 케이스에 대해 설명한 적이 있다. 

그 중 하나의 케이스로 데이터의 비교시 int보다 작은 타입들은 모두 signed int 형태로 자동 형 변환이 일어나게 된다. 

 

따라서 실제 값은 아래와 같이 변경된다. 

1
2
3
4
5
6
7
8
9
10
11
12
int main(void){
    unsigned short val = -1;
    signed short val2 = -1;
    if(val == val2){    // (int)val == 0x0000FFFF, (int)val2 == 0xFFFFFFFF
        printf("val == val2\n");
    }
    else{
        printf("val != val2\n");
    }
    return 0;
}    
    
cs

두개의 값이 signed int형으로 형 변환이 일어나게 되면

unsigned short는 추가된 크기에 0을 할당하여 값이 유지되고,

signed short는 부호 bit를 유효하게 유지하기 때문에 추가된 크기에 모두 부호를 나타내를 bit 1이 추가된다. 

 

따라서 초보자가 Firmware를 만드는 경우 정말 많이 실수를 하게 되는 부분이 unsigned를 사용하지 않고 기본형인 shrot, int8, int16 등을 사용하는 것이다. 

사실 Firmware에서 signed값을 사용하는 케이스는 생각보다 많지 않고, 만약 자동 형 변환에 따른 리스크를 감수하기 싫다면 우선 모든 변수를 int or unsigned int로 선언하여 작업하는 것을 추천한다.

728x90