전처리기 지시문

#define , #error, #if / #elif / #else 및 #endif / #ifdef와 #ifndef

 

 

 

전처리기 지시문은 일반적으로 소스 프로그램을 쉽게 변경하고 여러 실행 환경에서 쉽게 컴파일할 수 있도록 하기 위해 사용된다.

전처리기(=선행처리)란 컴파일 이전의 처리를 의미하고 소스파일은 컴파일러에 의해 컴파일 되기 이전에 이 전처리기 단계를 거친다.

 

 

 

◎ #define 지시문

이 #define 지시문은 세 부분으로 나뉜다.

#define PI 3.1415
지시자 매크로 매크로 몸체

많이 쓰이는 PI로 예시를 들어보면 코드에서 PI라는 이름(매크로)이 나오면 3.1415(매크로 몸체)로 바꾸라는 명령과 같다.

 

#define PI 3.1415

int function_before()
{
	int angle;
	angle = 180 * PI;
}

int funcint_after()
{
	int angle;
	angle = 180 * 3.1415;
}

 

전처리기의 단계를 거치면 코드 상에서 function_before의 내용을 function_after로 바꾼다.

이렇게 상수를 매크로로 정의한 것을 매크로 상수라고 부르고

상수가 아닌 함수로 정의해 놓은 것을 매크로 함수라고 부른다. 

 

 

 

 

◎ #if, #elif, #else 및 #endif 지시문 

#if... #endif는 조건부 코드 삽입을 위한 지시문이다. 

소스파일의 각 #if 지시문은 #endif 지시문과 일치해야 하며 #if와 #endif 사이에는 여러개의 #elif가 나올 수 있지만 #else는 하나만 사용할 수 있다.

 

#define ENABLE 1
#define IMPOSSIBLE 0


int main()
{
#if ENABLE
	cout << "ENABLE" << "\n";
#endif IMPOSSIBLE
	cout << "IMPOSSIBLE" << "\n";
}

 사용법은 이처럼 if문이 나오면 반드시 endif가 나와야 하며 ENABLE이 참(=1)이라면 cout << "ENABLE" << "\n"; 의 코드를 삽입하고 IMPOSSIBLE이 참이라면 cout << "IMPOSSIBLE" << "\n";의 코드를 삽입하라는 뜻이다. 

 

 

 

 

 

 

◎ #ifdef 및 #ifndef 지시문

정의 된 연산자와 함께 사용될 때 #if 지시어와 동일한 효과를 가진다.

 

#ifndef 식별자
#ifndef 식별자

이 지시문은 아래의 지시문과 같은 내용이다.

#if 정의된 식별자
#if! 정의된 식별자

 

#if는 매크로가 참인지 거짓인지에 따라서 동작한다면 #ifdef는 매크로가 '정의되어 있는지 아닌지'를 기준으로 동작한다. 

#ifdef는 매크로가 정의되어 있다면이고

#ifndef는 매크로가 정의되어 있지 않다면이라는 의미이다. 

 

 

 

 

◎ #error 지시문

전처리기가 해당 지시문을 발견하면 컴파일이 중지되고 여기에 포함된 오류 메시지가 전달된다. 

#define _EXIT

#ifdef _EXIT
#error "Error exists."
#endif

 

전처리기가 해당 코드를 만나게 되면 error.c : error: #error "Error exists." 이렇게 출력되며 종료된다. 

 

 

 

 

 

이 외에도 #import, #include, #line, #undef, #using 등이 전처리기 지시문에 포함된다. 

 

 

 

 

 

참고 자료;

 

https://docs.microsoft.com/ko-kr/cpp/preprocessor/preprocessor-directives?view=vs-2019

 

전처리기 지시문

전처리기 지시문Preprocessor directives 이 문서의 내용 --> #define, #ifdef과 같은 전처리기 지시문은 일반적으로 소스 프로그램을 쉽게 변경하고 여러 실행 환경에서 쉽게 컴파일할 수 있도록 하는데 사용됩니다.Preprocessor directives, such as #define and #ifdef, are typically used to make source programs easy to change and easy to

docs.microsoft.com

 

 

 

매크로 함수와 인라인(Inline) 함수

in은 '내부', line은 '프로그램 코드라인'을 의미한다.

즉 프로그램 코드라인 안으로 들어가 버린 함수라는 뜻이다.

매크로, 일반 함수, 인라인 함수 모두 결과는 동일하지만 결과를 위한 과정이나 성격은 상당히 다르다! 

 

 

 

 

◎ 매크로 함수

#define 선행 처리 지시문에 인수로 함수의 정의를 전달해서 함수처럼 동작하는 매크로를 만드는 것이다. 

물론 일반 함수와는 달리 단순 치환만을 해주므로, 일반 함수와 완전히 똑같은 방식으로 동작하지는 않는다. 

매크로 함수는 일반적인 함수에 비해 실행 속도에서 이점이 존재하지만 가독성도 떨어질 수 있고 디버깅도 어려우며 복잡한 함수를 매크로의 형태로 정의하는 것에 한계가 존재한다. 

빠른 이유?

더보기

일반 함수처럼 호출된 함수를 위한 스택 메모리의 할당을 할 필요도, 실행위치의 이동과 매개변수로의 인자를 전달할 필요도, return 문에 의한 값의 반환을 할 필요도 없기 때문이다. 

 

 

매크로 함수의 예시.

#define Add(x) ((x)+(x))

int main()
{
	int a = Add(3);
	cout << a << endl;
}

이렇게 실행하면 a의 출력값은 6이 나올 것이다. 

 

 

왜 '전처리 과정'을 거칠까?

더보기

#와 ## 연산자는 선행처리기 연산자이다. 

이 선행처리기 연산자는 전처리기-> 어셈블러로 넘어가기 전에 전처리기가 # 뒤에 붙은 코드들을 처리하기 때문이다. 그래서 전처리 과정에서 처리한다. 

 

 

그리고 이 과정은 

#define Add(x) ((x)+(x))

int main()
{
	int a = Add(3);
	cout << ((3)+(3)) << endl;
}

이런 과정을 거치게 되는데 위와 같이 함수의 몸체 부분이 함수 호출 문장을 완전히 대체했을 때 '함수가 인라인화 됐다'고 표현한다. 

 

 

 

 

◎ 인라인 함수

인라인 함수는 매크로 함수의 장점은 유지하고 단점은 제거했다고 볼 수 있다.

 

또한 인라인 함수는 inline 예약어를 빼면 기존 함수와 다를 바 없고 자료형 등이 지정돼 있어 문법적으로도 완벽한 함수이다. 

매크로를 이용한 함수의 인라인화는 전처리기에 의해 처리되지만 키워드 inline을 이용한 함수의 인라인화는 컴파일러에 의해 처리된다. 

 

inlineint Add(int x)
{
	return x+x;
 }

int main()
{
	int a = Add(3);
	cout << a << endl;
}

 

그러나 매크로 함수의 장점을 인라인 함수가 완벽하게 가져오지 못한 부분도 있다.

예를 들면 위의 매크로 함수의 예시에서 x는 자료형에 의존적이지 않다. 

즉 실수를 넣든, 정수를 넣든 데이터 손실이 발생하지 않는다.

3을 넣으면 6이 1.92를 넣으면 3.84가 나오게 된다. 

하지만 인라인 함수는 자료형 기반으로 정의된 함수이기 때문에 int 자료형 기반에서 1.92를 넣게 되면 0.84의 손실이 발생한다. 

 

물론 함수의 오버로딩을 통해 문제 해결이 가능하지만 간단하게 한 번만 정의하면 된다는 매크로 함수의 장점과는 멀어지게 된다.

그런데 C++에는 이에 대한 해결책이 또 하나 존재한다. 바로 템플릿을 이용하는 것이다. 템플릿을 이용하면 여러 번 정의하지 않아도 한 번에 해결된다!

 

 

 

 

 

◎ 추가

Visual Studio를 통해 컴파일할 경우, 인라인으로 선언하지 않았더라도 적합하면 인라인 함수로 확장하는 설정이 있다.

반대로 인라인으로 선언했다고 해도 적합하지 않다면 일반 함수로 컴파일한다. 

 

기본값은 '인라인 함수로 사용하는 데 적합한 함수는 모두 인라인 함수로 만든다'는 의미이다. 

설정값은 보통 '기본값'으로 지정돼 있다.

 

 

 

 

 

 

 

참고 출처;


http://tcpschool.com/c/c_prepro_macroFunc  (코딩의 시작, TCP School ; 매크로 함수)

 

코딩교육 티씨피스쿨

4차산업혁명, 코딩교육, 소프트웨어교육, 코딩기초, SW코딩, 기초코딩부터 자바 파이썬 등

tcpschool.com


윤성우의 열혈 C 프로그래밍 ( 저; 윤성우, 출판사 ; 오레지 미디어)


이것이 C++이다 ( 저; 최호성, 출판사 ; 한빛미디어 )

 

 

 

 

+ Recent posts