#ifdef __cplusplus

c or linux 2005. 2. 12. 20:39


#ifdef __cplusplus
extern "C" {
#endif

C++파일이면 extern "C" { 이 구문을 추가하라는 얘깁니다.
이 헤더파일이 C++에서 사용될 경우 C 파일에서 정의된 함수는 C++에서
사용할 수 없기 때문에 미리 정의해놓은 것이지요..

#ifdef __cplusplus
extern "C"
{
#endif

C함수 선언들...

#ifdef __cplusplus
}
#endif

 

 

전처리기에서 가장 먼저 수행 되는 부분 입니다. 선행처리기라고도 합니다. 종류로는 #define, #if, #ifdef, #ifndef, #defined, #undef가 있습니다. 이것은 기존에 있는 방대한 소스 코드를 지우지 않고 활성화 비활성화 하는데 가장 많이 이용 합니다. 기존에 있는 소스를 건드리지 않는 상태에서 부분적으로 컴파일 하는곳에 쓰입니다.

 

#define

구문의 상수로 치환할때 쓰입니다. 대체해서 쓰겠다는 뜻입니다.

또한 #define은 함수 역활 비슷하게 매크로로써 쓰일수 있습니다.

#define SUM(x) ((x) = (x)+(x))

이렇게 쓰일수 있습니다. 동작원리는 함수와 같습니다. 말 그대로 main소스에서 SUM을 호출하면 옆에 있는 더하기 코드가 치환되는 것입니다.

 

#ifdef, #ifndef

(#ifndef __헤더명_H__)

헤더파일이 겹치는 것을 막기위한 일종의 매크로입니다. 예를들어 헤더파일에다가 어떤 클래스의 인터페이스 선언을 넣었다고 합시다. 이 클래스 인터페이스에서 다른 파일의 프로토타잎이 필요해서 다른 A 파일을 include 하고 있는데 이 헤더 파일을 include 하는 파일에서 A라는 헤더 파일을 이미 include 하고 있다면 두번 define한 것이 됩니다. 그러면 SYNTEX 에러가 나겠지요. 그래서 그런것을 막는 방법의 하나로 #ifndef을 제공합니다. 이전에 include되어 있으면 #endif쪽으로 점프해버려 결국 한번 선언되는 것입니다.

예를 들어

#include  <stdio.h>    ------ (a)

#include  <stdio.h>    ------ (b)
두번 썼다고 합시다. 그런데 앞에 이미 include를 했는데 밑에 또 한다면 문제가 되겠죠. 컴파일러가 검사해야할 코드량도 많아지구요.

그래서 stdio.h 에는

#ifndef _STDIO_H

#define _STDIO_H

가 선언되어 있습니다.

만약 _STDIO_H가 선언되어 있지 않다면 선언한다는 뜻이죠. 그 뒤 (b)에서는 이미 (a) 쪽에서 _STDIO_H 을 선언한 상태이기 때문에 전처리기 쪽에서 무시해버립니다. 그럼 컴파일러는 (a)만 검사하겠죠.


컴파일할 때

#ifdef HAHAHAHA

               printf("HAHAHAHA");

#else

               printf("HOHOHOHO");

#endif

와 같이 쓰면 만약 HAHAHAHA가 선언되어 있다면 printf("HAHAHAHA");를 전처리기가 컴파일러에게 넘겨주고 아니라면 printf("HOHOHOHO"); 를 넘겨줍니다. 컴파일할 때 전처리기에게 옵션을 줄 수 있습니다. 이것을 보통 preprocessor definition 이라고 하는데요, 전처리기에게 "HAHAHAHA가 있는 부분을 포함시켜!" 라고 옵션을 주는 것이죠. 보통 컴파일러마다 제공합니다. 비주얼 스투디오도 셋팅에 보면 있구요, gcc는 gcc -DHAHAHAHA .......... 와 같이 하면 되죠.

 

#if

#if 구문은 if랑 아주 비슷합니다.

이것은 어떠한 구문을 컴파일 할지 안할지를 지정할수 있습니다.
#define A 1
#if A
    source code.....
#endif
위에는 소스는 컴파일이 됩니다. if문에서와 같이 참, 거짓을 구분하여 컴파일 됩니다. 위에서 A값은 1...즉 0보다 큰수 이기 때문에 참으로 돌아가는 것입니다. 직접 #if 0 .... #endif 이렇게 하면 거짓이기 때문에 이 부분은 컴파일이 되지 않습니다.

 

#defined

여러개의 define이 되어져 있는지를 검사할때 쓰입니다. 이것은 여러개를 동시에 검사 할수 있습니다.

#if #defined A || #defined B

 

#undef

위에서 define된 것을 무효화 시키는 것입니다. 예를 들면

#define A 10

이렇게 되있고 뒤에서

#undef A

이렇게 하면 A로 디파인된 값은 무효화 되는 것입니다.

 

 

프로그래머들 마다의 코딩 스타일(암시적 약속)이 있습니다. 보통 매크로, const 변수는 대문자로 적는 것이 원칙입니다. 매크로 함수와 일반함수, 매크로대상체(object-like macro)와 일반변수를 구분하기 쉽게 해주는 것이지요.

#define STDIO_H_

왜 뒤에 _를 붙였을까요? 이것도 하나의 암시적 약속입니다. 컴파일러 제작회사는 매크로를 정의할 때 사용자들과 이름이 충돌이 나지 않게 하기 위해서 대부분 _를 뒤어 덧붙입니다. 또한 _를 하나 혹은 두개연속으로 시작하는 것은 컴파일러 내부에서 사용하는 매크로라는 성격이 강합니다. 물론 강제적인 뜻은 없으며 단지 관습상 그렇습니다. 왜 이것이 관습이 되었나하면 보통 매크로 변수이름이나 함수이름을 지을때 뒤에 _를 붙이지 않기 때문입니다. 그래서 함수제작자들이 _를 단골로 붙였습니다.

 

다음과 같은 매크로는 컴파일러 내부에서 실제로 쓰이며 표준 C에서 인정한 매크로들 입니다. 설마 사용자가 이런 매크로를 정의해서 사용하지는 않겠죠? 물론 다시 정의하면 오류가 나게 됩니다.

__LINE__

__FILE__

__DATE__

__IME__

__STDC__

__STDC

_VERSION__

printf("%d\n", __LINE__); 과 같이 실제로 찍어볼 수도 있습니다.

 

사실 매크로명은 마음대로 지어도 상관없습니다. 하지만 경력이 많은 C 프로그래머들이 암시적으로 써온 약속들이 있기 때문에 대부분 그렇게 하는 것입니다. 내부적으로 해석되는 것은 토큰이 하나 이상만 되면 모두 매크로 정의가 되는 것이며 하나일 경우 치환은 되지 않습니다.

 

 

C의 predefined macro

__FILE__ a string that holds the path/name of the compiled file
__LINE__ an integer that holds the number of the current line number
__DATE__ a string that holds the current system date
__TIME__ a string that holds the current system time
__STDC__ defined as the value '1' if the compiler conforms with the ANSI C standard
__cplusplus determines if your compiler is in C or C++ mode. Usually used in headers

 

예)

#include <stdio.h> 
 
void main(void) 

    printf("The path/name of this file is %s\n", __FILE__); 
    printf("The current line is %d\n", __LINE__); 
    printf("The current system date is %s\n", __DATE__); 
    printf("The current system time is %s\n", __TIME__);  

    #ifdef __STDC__ 
        printf("The compiler conforms with the ANSI C standard\n"); 
    #else 
        printf("The compiler doesn't conform with the ANSI C standard\n"); 
    #endif 
    #ifdef __cplusplus 
        printf("The compiler is working with C++\n"); 
    #else 
        printf("The compiler is working with C\n"); 
    #endif 

 


 

'c or linux' 카테고리의 다른 글

POSIX 쓰레드로 멀티 쓰레드 프로그래밍하기  (0) 2005.02.18
함수 포인터  (0) 2005.02.16
ctags 활용  (0) 2005.02.15
#ifdef __cplusplus  (1) 2005.02.12
Setjmp()  (0) 2005.02.11
C언어 함수  (0) 2005.02.05
Posted by 김용환 '김용환'

댓글을 달아 주세요

  1. 안아론 2012.03.20 15:07  댓글주소  수정/삭제  댓글쓰기

    정말 유익한정보를 알기쉽게 써주셧네요ㅎㅎ 많이배우고갑니다!