최상단

컨텐츠

[C] #define을 사용할 경우 디버깅 쉽게 하기.

글 정보

Category
컴퓨터 이야기
2007. 5. 14. 15:44

본문

아침에 회사나오면서 잠시 생각했던 주제인데요.
분명 학교에서 배우길;........
컴파일을 수행하게 되면 define과 기타등등(;;ㅋㅋ)들은 precompile이 된다고 배웠습니다..
그리고 precompile을 마치고 실제 compile이 수행된다고 배웠죠?..
그래서 오늘 잠시 틈을 내서......gcc에서 precompile을 할수 있는 옵션을 찾았습니다^______^
precompile을 하기 위한 옵션은 -E 입니다.
그러면......precompile된 코드가..
standard output으로 화면에 쫘~~악 뿌려지게 되죠..

제가 이 precompile이 왜 필요하다고 생각했는지가 중요하겠죠?.
(넵-_-..저한테만 중요합니다;;)

가끔 개발을 하다보면..........
개인적으로 define을 많이 사용하는 것을 좋아하지는 않지만..
(개별 스타일 차이죠..)
다른 분들이 작성해놓으신 파일들을 디버깅 해야할 경우들이 가끔 있습니다.-_-;;
이럴 경우 진짜~ 진짜 ..가끔.. define을 잘못해 놓아 버그가 생기는 경우가 생기는데요..
define에서 버그가 있으면..잡기가 좀 어렵죠^^
특히 함수같은 것들은 define으로 해놓으시면..대략 난감..-_-
inline을 사용해도 될텐데;; 왜 굳이 define을 쓰셨는지는 모르겠지만;;
여튼..이러한 경우가 발생합니다-0-;

이러한 경우 precompile을 수행시킨 뒤 소스 코드를 보게되면..
define에 의해서 정의된 부분들이 모두 코드안으로 들어가게 되니까..
디버깅이 훨씬 쉬워지겠죠?.....
단..........주석은 싸그리다 지워집니다........;;;


#include <stdio.h>

/******************************************************************************
 * Author : thedino ( http://thedino.net )
 * Date : 2007. 5. 14
 * Comment : Gcc의 Precompiled 옵션을 사용하여 DEFINE 오류 찾아내기
 *****************************************************************************/

#define BIN_PRINT(_val_) \
    { \
        int __k__; \
        for ( __k__ = 0 ; __k__ < sizeof(_val_)*8 ; __k__++ ) { \
            if ( (1 << sizeof(_val_)*8-1) & _val_ << __k__ ) { \
                printf("1"); \
            } else { \
                printf("0"); \
            } \
            if ( (__k__+1) % 4 == 0 ) \
                printf(" "); \
        } \
        printf("==> %u",_val_); \
        printf("\n");\
    }

int main()
{
    BIN_PRINT(1);
    BIN_PRINT(4);
    BIN_PRINT(1123);
    BIN_PRINT(1024);
    BIN_PRINT(0x01020304);
    BIN_PRINT(0xFFFFFFFF);
    return 0;
}

(define에 의한 버그가 아니라면...-E옵션만 다시 지우면 되니까;;..뭐-_-)


여하튼...다음과 같은 프로그램이 있다고 생각해보세요-..
BIN_PRINT는 int형범위 내의 숫자를 이진수로 출력하는데는 아무런 지장이 없습니다.
이 프로그램을 다음과 같은 명령으로 precompile 하게 되면 다음과 같은 소스가 출력되죠..

# gcc -E precompiled_test.c


# 윗부분 생략!!//

# 2 "precompiled_test.c" 2
# 25 "precompiled_test.c"
int main()
{
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(1)*8 ; __k__++ ) { if ( (1 << sizeof(1)*8-1) & 1 << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",1); printf("\n"); };
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(4)*8 ; __k__++ ) { if ( (1 << sizeof(4)*8-1) & 4 << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",4); printf("\n"); };
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(1123)*8 ; __k__++ ) { if ( (1 << sizeof(1123)*8-1) & 1123 << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",1123); printf("\n"); };
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(1024)*8 ; __k__++ ) { if ( (1 << sizeof(1024)*8-1) & 1024 << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",1024); printf("\n"); };
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(0x01020304)*8 ; __k__++ ) { if ( (1 << sizeof(0x01020304)*8-1) & 0x01020304 << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",0x01020304); printf("\n"); };
        { int __k__; for ( __k__ = 0 ; __k__ < sizeof(0xFFFFFFFF)*8 ; __k__++ ) { if ( (1 << sizeof(0xFFFFFFFF)*8-1) & 0xFFFFFFFF << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",0xFFFFFFFF); printf("\n"); };

        return 0;
}

짜잔~~
위에 있는 소스랑 천지차이입니다-_-;;..
뭐..여튼..................결과는

0000 0000 0000 0000 0000 0000 0000 0001 ==> 1
0000 0000 0000 0000 0000 0000 0000 0100 ==> 4
0000 0000 0000 0000 0000 0100 0110 0011 ==> 1123
0000 0000 0000 0000 0000 0100 0000 0000 ==> 1024
0000 0001 0000 0010 0000 0011 0000 0100 ==> 16909060
1111 1111 1111 1111 1111 1111 1111 1111 ==> 4294967295

요렇게 잘 나오죠..이쁘게;

하지만..

프로그램의 끝에

BIN_PRINT(0xFFFFFFFFFFFF);

를 추가하게 되면..어떻게 될까요?
이 값은 int형의 범위를 넘어선 값입니다..-0-.결국 (long long)형이 되는거죠.
컴파일을 하게 되면...

precompiled_test.c:33: warning: left shift count >= width of type
다음과 같은..깔끔한-_- 워닝만 하나 뜨고..결국 실행은 되죠;
결과는..

0000 0000 0000 0000 0000 0000 0000 0001 ==> 1
0000 0000 0000 0000 0000 0000 0000 0100 ==> 4
0000 0000 0000 0000 0000 0100 0110 0011 ==> 1123
0000 0000 0000 0000 0000 0100 0000 0000 ==> 1024
0000 0001 0000 0010 0000 0011 0000 0100 ==> 16909060
1111 1111 1111 1111 1111 1111 1111 1111 ==> 4294967295
0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000 0000

==> 4294967295

자~..드디어 문제가 생겼습니다..;;(억지로 문제를 만들고 ㅈㄹㅈㄹ)

precompile 옵션으로 다시 컴파일을 해서 보면.

{ int __k__; for ( __k__ = 0 ; __k__ < sizeof(0xFFFFFFFFFFFF)*8 ; __k__++ ) { if ( (1 << sizeof(0xFFFFFFFFFFFF)*8-1) & 0xFFFFFFFFFFFF << __k__ ) { printf("1"); } else { printf("0"); } if ( (__k__+1) % 4 == 0 ) printf(" "); } printf("==> %u",0xFFFFFFFFFFFF); printf("\n"); };

라는 코드가 추가가 됐는데요..
어디가 잘못됐을까요?...
   1 << sizeof(0xFFFFFFFFFFFF)*8-1
넵..이쪽이 잘못됐습니다............왜냐하면 1을 int형으로 간주하기 때문에
sizeof(0xFFFFFFFFFFFF)*8-1 의 값은...........63이 나올 것이고..
그럼..0000000000...00000000 이렇게 나오겠죠-_-;

해결방법은?........
저는..
1 << 이 방법 대신..
1 은 그대로 두고.......비교할 대상을 첫번째 자리수까지 내려서..했습니다.

#define BIN_PRINT(_val_) \
    { \
        int __k__; \
        for ( __k__ = sizeof(_val_)*8-1 ; __k__ >= 0 ; __k__-- ) { \
            if ( 1 & (_val_ >>  __k__) ) { \
                printf("1"); \
            } else { \
                printf("0"); \
            } \
            if ( (__k__) % 4 == 0 ) \
                printf(" "); \
        } \
        printf("==> %u",_val_); \
        printf("\n");\
    }

이러한 식으로..............

에고........뭐..precompile 하나 설명하면서 잡스러운 말들만 많이 한듯하네요.
그럼..이만..휘리릭~

트랙백과 댓글 여닫기

TOP