Computer >> 컴퓨터 >  >> 프로그래밍 >> C 프로그래밍

C 언어 조건부 컴파일 완벽 정리: #if, #ifdef, #ifndef부터 #pragma까지

C 프로그래밍 언어에서는 여러 전처리기 지시자를 사용해 프로그램 코드의 특정 부분을 선택적으로 컴파일할 수 있습니다. 이를 조건부 컴파일(Conditional Compilation)이라고 하며, 대표적인 지시자는 다음과 같습니다.

  • #if
  • #else
  • #elif
  • #endif

#if 지시자

#if의 일반적인 형식은 다음과 같습니다.

#if 상수_표현식
실행할 문장들
#endif

상수 표현식이 참(0이 아닌 값)으로 평가되면 해당 블록 안의 코드가 컴파일되고, 그렇지 않으면 컴파일러가 무시합니다.

#else와 #elif

#else는 C 언어의 else 키워드와 거의 같은 방식으로 동작합니다. 앞선 조건이 거짓일 때 컴파일할 코드를 지정합니다.

#elif는 "else if"를 의미하며, 여러 조건을 연속해서 검사하는 if else-if 형태의 컴파일 체인을 만들 수 있습니다.

#if 0을 활용한 주석 처리

#if는 코드를 임시로 비활성화하는, 즉 "주석 처리"하는 대체 방법으로도 유용하게 사용됩니다.

#if 0
printf("%d", total);
#endif

위 예제에서 컴파일러는 printf("%d", total); 문장을 완전히 무시합니다. 여러 줄의 코드를 한 번에 제거할 때 /* */ 주석보다 편리하고 중첩 문제도 없어 실무에서 자주 활용됩니다.

#ifdef와 #ifndef

#ifdef는 "if defined(정의되어 있다면)"를 의미하며, 반드시 #endif로 종료해야 합니다. 매크로가 정의되어 있으면 블록 내부의 코드가 컴파일됩니다.

#ifndef는 "if not defined(정의되어 있지 않다면)"를 의미하며, 매크로가 정의되어 있지 않을 때 코드를 컴파일합니다. 헤더 파일의 중복 포함을 방지하는 include guard 패턴에 널리 사용됩니다.

#undef

#undef는 이전에 정의된 매크로 정의를 제거하는 지시자입니다. 정의가 삭제된 이후에는 해당 매크로가 존재하지 않는 것처럼 동작합니다.

#line

#line은 __LINE__과 __FILE__의 내용을 변경합니다. __LINE__은 현재 컴파일 중인 코드의 줄 번호를 담고 있으며, __FILE__은 컴파일 중인 소스 파일의 이름을 담은 문자열입니다. 두 식별자 모두 컴파일러에 미리 정의되어 있는 predefined identifier입니다.

#pragma

#pragma 지시자는 구현체마다 다르게 정의되는(implementation-defined) 지시자로, 컴파일러에게 다양한 명령이나 옵션을 전달할 수 있게 해줍니다. 컴파일러 경고 제어, 최적화 설정 등 컴파일러별 고유 기능을 사용할 때 활용됩니다.

예제 코드

다음은 #ifdef, #ifndef, #else, #endif의 동작을 보여주는 C 프로그램입니다.

#include <stdio.h>
#define a 10

void main(){
#ifdef a
printf("\n Hello I am here..");
#endif

#ifndef a
printf("\n Not defined ");
#else
printf("\n R u There ");
#endif
}

실행 결과

위 프로그램을 실행하면 다음과 같은 결과가 출력됩니다.

Hello I am here..
R u There

매크로 a가 10으로 정의되어 있으므로 #ifdef 블록의 코드가 컴파일되어 첫 번째 메시지가 출력됩니다. 또한 #ifndef 조건은 거짓이 되므로 #else 블록의 코드가 컴파일되어 두 번째 메시지가 출력됩니다.