C 형변환은 문법보다 결과가 언제 달라지는지를 먼저 봐야 합니다.
숏컷 코드
- 정수 나눗셈
- signed/unsigned 혼합
- 큰 타입에서 작은 타입으로의 축소
int total = 7;
int count = 2;
double a = (double)total / count; // 3.5
double b = (double)(total / count); // 3.0문법
캐스팅은 단순히 “이 타입으로 바꾼다”가 아니라 언제 변환이 일어나는가를 같이 봐야 합니다.
- 앞은 나누기 전에 실수로 바뀜
- 뒤는 정수 나눗셈이 끝난 뒤에 바뀜
실전에서는 "언제 변환되느냐"가 중요합니다.
손실 구간
int n = -1;
unsigned int u = 1;
if (n < u) {
/* 기대와 다를 수 있음 */
}이 문제는 비교 전에 타입이 맞춰지기 때문입니다. 음수가 큰 양수처럼 해석될 수 있어서 결과가 뒤집힙니다.
즉 unsigned가 끼는 순간 비교식은 더 조심해서 읽어야 합니다.
double d = 3.9;
int n = (int)d; // 3
int big = 300;
char c = (char)big;캐스트는 "안전하다"는 뜻이 아니라 "내가 이 손실을 감수한다"는 표시입니다.
변환 규칙
char a = 100;
char b = 20;
int sum = a + b;여기서는 char끼리 계산하는 것이 아니라, 보통 int로 승격된 뒤 계산합니다. 그래서 C는 표면상 작은 타입을 써도 연산 안에서는 더 큰 타입으로 움직이는 경우가 많습니다.
체크포인트
- 정수 나눗셈 결과를 실수로 바꾸고 싶을 때
- 포인터 타입을 명시적으로 보여주고 싶을 때
- 범위 축소를 의도적으로 드러내고 싶을 때
unsigned가 섞이면 비교 결과를 다시 확인- 작은 정수 타입도 연산 전에 승격될 수 있음
하지만 캐스트가 많아질수록 "원래 타입 설계가 불편한 것 아닌가"도 같이 의심해야 합니다.
주의할 점
캐스트는 버그를 고치는 도구가 아니라, 변환을 강제로 통과시키는 도구이기도 합니다. 경고를 없애려고 캐스트부터 넣기 시작하면 오히려 더 위험해집니다. 먼저 왜 타입이 안 맞는지 보는 편이 맞습니다.
참고 링크
1 sources