글을 시작하기 전에 문제를 하나 제시한다.
typedef enum {RESET = 0, SET = !RESET} BitAction;
BitAction readInputDataBit(Pin pin);
...
void main() {
if (readInputDataBit(buttonPin) == SET) {
printf("button is set!\\n");
} else {
printf("button is reset!\\n");
}
}
위의 코드는 버튼 동작을 테스트하기 위한 코드를 간소화 한 것이다. BitAction과 readInputDataBit 함수는 library형태로 주어진다.
언뜻 보면 잘 돌아갈 것 처럼 보이지만, main함수에 문제가 존재한다. 어디가 문제일까? 한방에 알아차린다면 당신은 👽👍.
코드를 더 깊이 파고들어보자.
typedef struct PIN_struct {
uint8_t value;
} PIN;
BitAction readInputDataBit(Pin pin) {
return (BitAction) pin.value;
}
위의 코드는 실제 API 코드를 간소화한 것이다. 참고로 pin.value의 실제 값이 어떻게 들어올지는 아직 모른다.
이제 어디가 문제인지 보이는가?
예시 동작 시나리오를 한번 그려보자. 만약 pin.value의 값이 1이라고 가정해보자.
readInputDataBit함수에서 pin.value를 BitAction으로 타입캐스팅하면 1은 0이 아니고 즉, RESET이 아니기 때문에 SET이 된다. main함수에서 이 값은 " == SET"과 비교를 하고 참이기 때문에 "button is set"이 출력될 것이다.
그렇다면, 만약 pin.value의 값이 2라면 어떻게 될까?
마찬가지로 pin.value의 값을 타입캐스팅 하면 0이 아니기 때문에 SET이 될 것이다. 그리고 이 값은 main함수에서 " == SET"과 비교를 한다. 과연 SET은 SET일까..?
이제 본론으로 들어가자.