참과 거짓을 나타내는 방법이 C와 C++에서 다릅니다.
C 언어는 대문자 BOOL 자료형을 사용하고
C++는 소문자 bool 자료형을 사용합니다.
둘 다 참과 거짓을 표현하기 위해 만들었지만, 내부는 완전히 다르고 호환되지 않습니다.
일단 BOOL 자료형이 C 언어에는 없습니다.
대문자 BOOL 자료형을 사용하려면 typedef를 통해 재정의해야 합니다.
typedef int BOOL;
이제 int와 BOOL은 같은 자료형이 되었고, BOOL 자료형을 사용할 수 있습니다.
문제는 BOOL 자료형의 근본이 int 자료형이기 때문에
2나 3의 값도 잘 받아들인다는 것입니다.
앞서 말했듯이 항상 거짓인 0과 비교해야 하는 이유입니다.
여기에 대문자 TRUE와 FALSE를 사용하기 위해 enum이나 define으로 상수를 정의합니다.
#define FALSE 0
#define TRUE 1
아니면
enum { FALSE, TRUE };
처럼 사용해도 됩니다.
다만 정수에 대해서만 정의했고, 둘 다 int 상수라는 점입니다.
자료형과 값을 따로따로 설정하는 것이 번거로워서
다음처럼 한번에 처리하기도 합니다.
typedef enum { FALSE, TRUE } BOOL;
그러나, 여전히 BOOL 자료형의 근본이 int 자료형이라는 것에는 변함이 없습니다.
BOOL sw = -1;
에러나지 않는 코드입니다.
-1을 의도적으로 넣는 분은 없겠지만,
실수했을 때 컴파일러가 잡아주지 않기 때문에
나중에 치명적인 버그로 나타납니다.
C++인 경우에는 이 코드에서 FALSE와 TRUE만 사용해야 에러가 나지 않습니다.
C++에서는 참과 거짓에 대한 단점을 보완하기 위해
C 언어에 없는 새로운 자료형은 제공했는데, 그게 소문자 bool 자료형입니다.
bool sw = -1;
이제 이 코드는 에러입니다.
bool 자료형에는 소문자 true와 false만 넣을 수 있습니다.
그러나, VC++ 6.0에서는 에러가 발생하지 않고,
닷넷 컴파일러에서는 가벼운 에러를 뜻하는 경고(warning)가 뜹니다.
true와 false만 넣기 위해 만든 자료형에 -1을 넣는다는 것이
무슨 뜻인지 알 수 없기 때문에, 경고를 발생시키는 것이 맞습니다.
BOOL 자료형과 TRUE, FALSE 상수를 정의했다고 가정합니다.
BOOL sw1 = TRUE;
BOOL sw2 = true; // VC++ 6.0에서 에러
bool sw3 = TRUE;
bool sw4 = true;
6.0에서는 에러가 발생하지 않아도 될 부분에서 에러가 발생합니다.
bool 자료형의 크기는 1바이트로,
정확하게 0과 1을 표현하기 때문에 1바이트 정수를 4바이트 정수에 넣는 코드에서 에러가 발생하고 있습니다.
닷넷 컴파일러에서는 전혀 에러가 발생하지 않습니다.
분명 BOOL과 bool 자료형은 다른 자료형임에도
컴파일러 내부적으로 0과 1의 값을 갖는지 판단하는 것 같습니다.
sw3과 sw4에 0과 1이 아닌 값을 넣으면 경고가 뜹니다.
상수로 정의하지 않더라도 0과 1을 넣으면 문제가 없습니다.
표준은 아니지만, 컴파일러 확장 옵션이라고 생각됩니다.
리눅스와 윈도우 프로그래밍, 즉 C 언어를 벗어나서 운영체제에 특화된 코딩을
시스템 프로그래밍이라고 부릅니다.
윈도우에서는 Win32 API 프로그래밍이라고 부르고,
리눅스에서는 정직하게 시스템 프로그래밍이라고 부릅니다.
운영체제를 C 언어로 만들었다고 하는 것은
C++에서 제공하는 bool 자료형을 API에서 볼 수 없다는 것을 뜻합니다.
파일 확장자를 cpp로 주면,
여러분은 bool 변수를 만들어쓸 수는 있지만,
성공 여부를 반환하는 시스템 함수(API)는 대문자 BOOL을 반환할 거라는 뜻입니다.
컴파일러에 따라, 앞서 설명처럼 경고 또는 에러가 발생하겠지만
호환되지 않을 수 있다는 사실을 인지하고 있으면,
형변환이라도 해서 사용할 수 있겠습니다.
당연히 C++ 라이브러리에서는
성공 여부를 반환하는 함수는 bool 자료형을 반환합니다.
STL에 들어있는 컨테이너의 멤버 함수인 empty()는
비어있을 때 true, 비어있지 않을 때 false를 반환합니다.
C 언어는 아쉽게도 BOOL 자료형조차 정의하지 않고 있기 때문에
0과 1을 반환할 것입니다.
저는 가능하면 bool 자료형을 사용하려고 노력합니다.
잘못될 수 있는 여지를 막아주고 있는데,
사용하지 않는다면 그게 오히려 이상하다고 생각합니다.
라이브러리와 충돌이 나는 부분은 형변환을 통해서 처리합니다.
namespace, 참조 변수 등등 C 언어에 없는 많은 개념을 저는 사용하고 있습니다.
조건 비교에서 true와 비교할 수 있다는 것만으로도 가치가 있다고 생각합니다.
강요하는 것은 아니고
어떤 자료형을 쓸지는 여러분이 직접 결정해야 합니다.
저는 여러분이 선택할 수 있도록 정확한 정보를 제공할 뿐입니다.
단순히 0과 1로만 판단될것이라면 bool 로 쓰고 0이 아닌 값을 참으로 볼때는 BOOL 로 쓰면 될것 같지만, 두개의 문자가 대소문자만으로 구별하기에는 약간 모호성이 존재 한다.
그리고 windows.h를 포함해야지만 BOOL을 쓸수 있다.(일반적인) 그렇기 때문에 bool 로 쓰는것으로 제약을 걸면 속편할것으로 생각 된다.
최근댓글