원문 : __FILE__ , __LINE__ 의 활용

#include <stdio.h>
void main() {
#line 1 "main.c"
        int i=2,j=3,k=4;
        printf("%d,%d,%d\n",i,j,k);
        printf("%s, %d\n",__FILE__,__LINE__);
        printf("%d\n",__LINE__);
#line 3897
        printf("%s, %d\n",__FILE__,__LINE__);
#line 0 "aaa.c"
        printf("%s, %d\n",__FILE__,__LINE__);
}

다음의 결과를 유추해 보세여..
시간 1분) 밑에 답을 보기 전에 꼭 먼저 생각해 보시길...
















2,3,4
main.c, 3
4
main.c, 3897
aaa.c, 0

이때 __LINE__은 현재 행의 번호를
__FILE__은 현재 파일명을 나타내는데
#line 매크로가 이값을 바꿔 줄수 있습니다.

이기법은 향후에 assert를 이용한 동적 디버깅에 많이 응용이
되니 눈여겨 봐야 합니다.

*gcc 버전 확인
gcc -v

*gcc로 컴파일

gcc로 컴파일할 파일명
ex)gcc test.c
a.out이라는 실행 파일이 생김
./a.out으로 파일 실행

*gcc로 실행파일 지정 컴파일
gcc -o test test.c

*gcc로 컴파일만 하고 링크하지 않기
gcc -c test.c

*두 개 파일을 부분 컴파일 후 링크시키고 실행
gcc -c a.c b.c
gcc -o a a.o b.o
./a

*헤더파일
헤더파일 중에 <>로 묶인 것과 ""로 묶인 것이 있다.
<>로 묶인 것은 /usr/include에서 파일을 검색하고,
""로 묶인 것은 현재 디렉토리 및 -I옵션을 준 디렉토리에서 헤더파일을 찾는다.
gcc a.c -I..
gcc a.c -I/usr/src/linux/include

-t 묶음 파일의 내용을 표시하는 옵션
ar t libc.a | less

정적 라이브러리 : a라는 확장자
공유 라이브러리 : so라는 확장자

라이브러리 만들기

ar r libtest.a test.o
-s 옵션 : 목차를 갱신하거나 생성해줌
ar s libtest.a
ar rs libtest.a test.o

라이브러리 사용
gcc -o test test.c -ltest
gcc -o test test.c -ltest -L.

-l옵션 뒤에 링크하고 싶은 라이브러리 이름을 써줌
라이브러리 파일의 이름에 공통적으로 붙는 lib는 빼주고, '.'을 포함한 확장자도 빼준 나머지를 씀
수학라이브러리인 libm.a를 링크하고 싶을 때는 -lm 과 같은 옵션을 붙여야 함

gcc의 기본 라이브러리 디렉토리
/lib, /usr/lib, /usr/local/lib

*도움말 man

ex) man errno
man -s 2 write (섹션 지정하는 옵션)

*에러 처리

#include <string.h>
char *strerror(int errnum);

#include <stdio.h>
void perror(const char* msg);

사용

#include<errno.h>
fprintf(stderr, "ERROR: %s\n", strerror(errno));
perror("error");

-출처 : 영진닷컴 Unix & Linux C programming

안녕하세요? 바람돌이입니다.
이번에는 간략하게 프로그래밍을 할 때의 팁을 이야기 하겠습니다.

보통 프로그램을 작성하다보면, 디버깅을 위해서 printf문을 사용할 경우가 많습니다.
또한, 배포를 한 뒤에도, 남들이 자신의 코드를 보고 디버깅을 해야하는 경우가 종종있죠.
이를 위해서 상용적인 코드에는 다음과 같은 Tip을 종종 사용하곤 합니다.

다음과 같은 코드를 header 파일에서 보신적이 있으실 겁니다.

#ifdef XXX_DEBUG
   #define print_debug(A) printf(A)
#else
   #define print_debug(A)
#endif

정확한 명칭은 다를 수 있습니다.

간단하게 살펴보면, "#ifdef"는 뒤에 전처리기명이 정의 되어있으면, 이라는 뜻입니다.
즉, XXX_DEBUG가 선언이 되어있으면, 코드 내에 있는 print_debug(A) 부분은 모두 printf(A)로 치환됩니다.
그리고, 선언이 되어있지 않으면, print_debug(A)는 모두 사라지게 되는 것이죠.

보통 우리는 함수내에 printf(A)를 직접 삽입합니다.
그리곤, 필요없는 상황이 된다면, 삭제를 하지요. 그러나, 매우 귀찮을 일이 될 것이며, 실수로 삭제를 하지 않거나 하는 상황이 발생합니다.

그러나, 위의 코딩 기법을 사용하게 되면, XXX_DEBUG를 선언하지 않는 이상 실제 코드(컴파일한 파일)엔 debugging 코드는 존재하지 않게 되지요.

게다가 만약, 다시 디버깅을 해야하는 상황이 된다면, (다 완성이 되었다고 생각했는데, 오류가 있거나, 버전업을 할 경우) XXX_DEBUG만 다시 선언하면, 곧바로 Debugging을 수행할 수 있습니다.

조금만 더 기법을 사용한다면, debugging을 level 별로도 수행 가능할 것이라 생각합니다.
그 부분은 추후 기법으로 남겨놓죠. @^-^@



전처리기에 대한 것을 더 알고 싶으시다면, #ifndef , #ifdef , #endif #pragma 등등을 검색해 보시기 바랍니다.







+ Recent posts