はじめに
ある時に職場で見かけたCのコードに、 #ifdef _WIN32
という条件付きコンパイル(コンパイルスイッチ)を見かけました。
以前に条件付きコンパイルを学んだ時には、条件として#define ~
で定義されたマクロが使われていましたが、今回見たコードを再確認しても #define _WIN32
というコードが見当たりませんでした。
そこで気になって調べてみたところ、#ifdef _WIN32
は定義済みマクロというものであることが分かりました。
今回はこの定義済みマクロについて調べた結果をまとめてみました。
学習環境
- 今回はpaiza.ioのC言語のエディタと、Visual Studio Community 2019を使いました。
定義済みマクロとは
- 今回の
_WIN32
というマクロは、Microsoft C/C++ コンパイラ (MSVC) で事前定義されているマクロだそうです。- 事前定義されていたため、
#define _WIN32
というコードが存在しなかったというわけです。
- 事前定義されていたため、
- 「定義済みマクロは引数を取らず、再定義することはできない」という特徴があるそうです。
- 事前に定義されているものに上書きできるとマズいので、これは当たり前の仕様だと感じました。
定義済みマクロ「_WIN32 」
コンパイル ターゲットが 32 ビットの ARM、64 ビットの ARM、x86、または x64 の場合、1 として定義されます。 それ以外の場合は、定義されません。
- 上記のMicrosoftの説明だと分かりづらいですが、平たく言うと「OSがWindows(32bit)であるか?」を判定するために使われるマクロだそうです。
「_Win32」を使った例
- 裏でgccを利用しているpaiza.io上とVisual Studio上では、実行結果が想定通り異なっていました。
- gcc上では
_WIN32
というマクロが定義されていないので、実行結果に違いが現れたということだと思います。
- gcc上では
Main.c
#include <stdio.h>
int main(void){
printf("処理開始...\n");
#ifdef _WIN32
printf("Windows環境に依存する処理\n");
#else
printf("Windows以外の環境に依存する処理\n");
#endif
printf("処理終了\n");
}
paiza.io上での実行結果
処理開始...
Windows以外の環境に依存する処理
処理終了
Visual Studio上での実行結果
処理開始...
Windows環境に依存する処理
処理終了
補足
- Linuxであるかを識別するには
__linux__
、Mac OSであるかを識別するには__APPLE__
というマクロがそれぞれ用意されているようです。 - 他にもコンパイラやCPUの種類を識別するマクロも用意されているようですが、こういったものを使いこなせるようになると初心者レベルを脱却できそうですね...