지난 포스팅에서 #ifdef를 이용해서 운영체제의 비트 수(32bit vs 64bit)에 따른 조건부 컴파일 방법에 대해 알아봤다.
운영체제의 비트 수 외에도 C언어는 운영체제(OS)마다 지원하는 API나 헤더 파일이 다르다는 점을 고려해서 코드를 짜야 한다. (예를 들면 윈도우에서는 windows.h를 써야 하고, 리눅스에서는 unistd.h를 쓰는 식)
이럴 때 조건부 컴파일을 이용하면 코드 수정 없이 컴파일러가 알아서 해당 OS용 코드를 골라내게 할 수 있다.
1. 조건부 컴파일 개념
조건부 컴파일은 전처리기(Preprocessor) 단계에서 이루어진다.
컴파일러가 실제 기계어로 번역하기 전, #ifdef나 #if 같은 지시문을 보고 "이 부분은 포함하고, 저 부분은 버려라"라고 판단하는 것이다.
운영체제마다 컴파일러가 미리 정의해둔 예약 매크로(Predefined Macros)가 있는데, 이를 활용하면 현재 어떤 환경에서 컴파일 중인지 쉽게 알 수 있다.
2. 주요 운영체제별 예약 매크로
컴파일러는 현재 어떤 환경에서 코드를 빌드하고 있는지 알 수 있도록 미리 약속된 매크로를 제공한다.
가장 흔히 쓰이는 운영체제별 매크로는 다음과 같다.
대소문자까지 정확해야 하니 주의하자.
Windows 환경
- _WIN32: 32비트와 64비트 Windows 모두에서 정의된다. Windows 환경임을 나타내는 가장 보편적인 기준이다.
- _WIN64: 64비트 Windows 환경에서만 정의된다.
- _MSC_VER: 마이크로소프트 비주얼 C++(MSVC) 컴파일러를 사용할 때 정의된다. 컴파일러 고유 기능을 쓸 때 유용하다.
Linux/Unix 환경
- __linux__: 리눅스 시스템에서 정의된다.
- __unix__: 유닉스 계열(Linux, BSD 등) 공통으로 사용될 때 정의된다.
Mac 환경
- __APPLE__ : Apple 플랫폼(주로 macOS/iOS 계열) 공통
- __MACH__ : Mach 기반(대부분 macOS에서 같이 정의)
| 운영체제 (OS) | 예약 매크로 |
| Windows (32/64bit 공통) | _WIN32 |
| Windows (64bit 전용) | _WIN64 |
| Linux | __linux__ |
| macOS (Apple 제품군) | __APPLE__ |
| Android | __ANDROID__ |
3. 예시 코드: OS 맞춤형 메시지 출력하기
윈도우의 비트수(32/64bit)와 리눅스 환경을 구분하는 예제
// platform_ifdef.c
#include <stdio.h>
int main()
{
// 1. 먼저 Windows 환경인지 확인
#if defined(_WIN32)
// 2. Windows 내부에서 64비트 여부 판별
#if defined(_WIN64)
printf("64bit MS Windows 환경이다.\n");
#else
printf("32bit MS Windows 환경이다.\n");
#endif
// 3. Windows가 아니라면 (보통 Linux/Unix)
#elif defined(__linux__)
printf("Linux 환경이다.\n");
#else
printf("알 수 없는 운영체제다.\n");
#endif
printf("조건부 컴파일 지시문 이후의 공통 코드를 실행한다.\n");
return 0;
}
- #if defined(_WIN32): 64비트 윈도우에서도 _WIN32는 정의되어 있다. 이는 과거 32비트 API와의 호환성 및 관례 때문이다. 따라서 윈도우 전체를 묶을 때는 이 매크로를 먼저 사용한다.
- 중첩 조건: 윈도우 안에서 다시 #if defined(_WIN64)를 사용해 비트수를 나눌 수 있다.
- #elif와 #else: if-else 문과 구조가 비슷하지만, 조건에 맞지 않는 코드 블록은 컴파일 결과물(바이너리)에 아예 포함되지 않아 효율적이다.
4. 조건부 컴파일을 하는 이유
- 이식성(Portability): 코드 하나로 윈도우, 리눅스, 맥 어디서든 컴파일할 수 있다. (크로스 플랫폼 개발)
- 효율성: 실행 시점에 if 문으로 체크하는 게 아니라, 컴파일 시점에 필요한 코드만 남기기 때문에 실행 파일이 가볍고 빠르다.
- 유지보수: OS별로 소스 파일을 따로 만들 필요가 없어 관리가 편하다.
💡 윈도우 64비트 환경에서는 _WIN32와 _WIN64가 모두 정의되어 있다. 따라서 64비트 전용 기능을 넣고 싶다면 #ifdef _WIN64를 먼저 체크하는 것이 좋다.
'Journey to Security > C언어' 카테고리의 다른 글
| C언어 구조체 포인터와 malloc 함수 (0) | 2026.02.25 |
|---|---|
| C언어 3중 포인터와 문자열 배열의 메모리 구조 (0) | 2026.02.24 |
| C 언어 배열의 문자열 수정과 strcpy의 동작 원리 (+strncpy) (0) | 2026.02.24 |
| C언어 조건부 컴파일: #ifdef (0) | 2026.02.24 |
| GDB TUI 모드: 소스 코드를 보며 디버깅하기 (0) | 2026.02.23 |