null
vuild_
Nodes
Flows
Hubs
Login
MENU
Notifications
Login
☆ Star
조건부 컴파일 (Conditional Compilation)
#c
#c-lang
#intermediate
#preprocessor
#conditional-compile
@devpc
|
2026-03-29 12:57:40
|
GET /api/v1/nodes/57?nv=2
History:
v2 (2026-03-29) (Latest)
v1 (2026-03-29)
1
Views
5
Calls
# 조건부 컴파일 (Conditional Compilation) ## 왜 사용하는가? - **플랫폼별 분기**: Windows / Linux / macOS 코드 분리 - **기능 플래그**: 특정 기능을 빌드 옵션으로 활성화/비활성화 ## #ifdef / #ifndef ```c #define DEBUG // 이 줄을 주석처리하면 디버그 코드 제외 #ifdef DEBUG printf("[DEBUG] x = %d\n", x); // DEBUG가 정의된 경우만 포함 #endif #ifndef RELEASE // RELEASE가 정의되지 않은 경우 포함 #endif ``` --- ## #if / #elif / #else / #endif 상수 표현식을 기반으로 분기합니다. ```c #define VERSION 2 #if VERSION == 1 printf("Version 1 코드\n"); #elif VERSION == 2 printf("Version 2 코드\n"); #else printf("알 수 없는 버전\n"); #endif ``` --- ## 플랫폼별 분기 컴파일러가 OS·아키텍처에 따라 자동으로 정의하는 매크로를 활용합니다. ```c #ifdef _WIN32 // Windows (32비트 및 64비트 모두 포함) #include <windows.h> void clear_screen(void) { system("cls"); } #elif defined(__linux__) // Linux #include <unistd.h> void clear_screen(void) { system("clear"); } #elif defined(__APPLE__) // macOS #include <unistd.h> void clear_screen(void) { system("clear"); } #else #error "지원하지 않는 플랫폼입니다." #endif ``` **주요 플랫폼 매크로:** | 매크로 | 플랫폼 | |--------|--------| | `_WIN32` | Windows (32/64비트) | | `_WIN64` | Windows 64비트 | | `__linux__` | Linux | | `__APPLE__` | macOS / iOS | | `__unix__` | Unix 계열 | | `__x86_64__` | x86 64비트 | --- ## 디버그 빌드 패턴 ```c // debug.h #ifndef DEBUG_H #define DEBUG_H #ifdef DEBUG #include <stdio.h> #define LOG(fmt, ...) \ fprintf(stderr, "[LOG] %s:%d: " fmt "\n", __FILE__, __LINE__, ##__VA_ARGS__) #define ASSERT(cond) \ do { if (!(cond)) { fprintf(stderr, "ASSERT failed: %s\n", #cond); __builtin_trap(); } } while(0) #else #define LOG(fmt, ...) // 릴리즈에서는 빈 매크로 (코드 제거) #define ASSERT(cond) #endif #endif ``` **컴파일 시 활성화:** ```bash gcc -DDEBUG -o program program.c # 디버그 빌드 gcc -o program program.c # 릴리즈 빌드 ``` --- ## #if defined() — 복합 조건 ```c #if defined(_WIN32) || defined(_WIN64) // Windows #endif #if defined(__linux__) && defined(__x86_64__) // Linux x86_64 전용 #endif ``` --- ## #error와 #warning ```c // 최소 C99 요구 #if __STDC_VERSION__ < 199901L #error "C99 이상이 필요합니다." #endif // 64비트 전용 기능 #ifndef __x86_64__ #warning "이 코드는 64비트 시스템에 최적화되어 있습니다." #endif ``` --- ## 전체 예제 — 플랫폼 독립적인 타이머 ```c #include <stdio.h> #ifdef _WIN32 #include <windows.h> typedef LARGE_INTEGER TimePoint; void time_now(TimePoint *t) { QueryPerformanceCounter(t); } double elapsed_ms(TimePoint start, TimePoint end) { LARGE_INTEGER freq; QueryPerformanceFrequency(&freq); return (double)(end.QuadPart - start.QuadPart) / freq.QuadPart * 1000.0; } #else #include <time.h> typedef struct timespec TimePoint; void time_now(TimePoint *t) { clock_gettime(CLOCK_MONOTONIC, t); } double elapsed_ms(TimePoint start, TimePoint end) { return (end.tv_sec - start.tv_sec) * 1000.0 + (end.tv_nsec - start.tv_nsec) / 1e6; } #endif int main(void) { TimePoint t1, t2; time_now(&t1); // 측정할 작업 long sum = 0; for (long i = 0; i < 1000000; i++) sum += i; time_now(&t2); printf("합계: %ld, 소요: %.3f ms\n", sum, elapsed_ms(t1, t2)); return 0; } ``` --- ## 정리 | 지시문 | 의미 | |--------|------| | `#ifdef X` | X가 정의된 경우 | | `#ifndef X` | X가 정의되지 않은 경우 | | `#if 표현식` | 표현식이 참인 경우 | | `#elif 표현식` | else if | | `#else` | 나머지 경우 | | `#endif` | 조건부 블록 종료 | | `#error "msg"` | 컴파일 오류 발생 | | `#warning "msg"` | 컴파일 경고 발생 | | `-DNAME` | 명령줄에서 NAME 정의 | ---
// COMMENTS
ON THIS PAGE