C/C++ 定義済みのプリプロセッサ定数による判断、推論方法
ユーザーの明示的な定義に依らないで、出来るだけコンパイラがセットするプリプロセッサ定数(マクロ定数)を使いたい。判断したいことは、
すべて独立な(直交する)概念ではなくて、絡んでいる。
このなかで、ビット数は32ビットオンリーなので、マクロ定数でゴチャゴチャしないで、サイズをsizeofで測ってマズイと思ったらstatic_assertで中断する。
↑が参考になる。自分のgistにコピーした。↓
MSCの情報は、
次の記事も参考になる。
Win32 APIが使えるか?
Windowsプラットフォームか?
これが厄介。問〈とい〉の立て方が「Windowsプラットフォームか?」というのが不適切な気がする。プラットフォームを問題にしている、というより、「Win32 APIを使う or 使わないで済ませる」の差。
- _WIN32 が定義されていても(つまり、Win32 API使えても) 、使いたくないときがある。
コンパイル時の意志によって切り替える。次の状況と選択がある。
ユーザーが意志を示すなら、USE_WIN32 のような定数を明示的に指定することになる。しかし、デフォルトが「使う」だとすると、否定である NO_WIN32 の導入が良さそう。
推測の方法
デフォルトは、「MSC, Win32, MFC使用」だから、これを否定する NO_WIN32, NO_MFC 定数を導入する。gccだからといってWindowsではない、とは言えない。
- NO_WIN32 ⇒ NO_MFC : 逆は成立しない
- __GNUC__ ⇒ NO_MFC : gccでMFCを使うことはないだろう
- !_MSC_VER ⇒ NO_MFC : 上の規則より強い。が、gccしか使わないなら上の規則と同値。
- !_WIN32 ⇒ NO_WIN32 : _WIN32が定義されてないなら、実際 Win32 APIは使えない。
問題は、NO_WIN32を結論するための前提が !_WIN32 だけか? ということ。_POSIX_SOURCE, _ANSI_SOURCE があれば、公的な規格ではないプラットフォーム固有の機能を使うべきではない、という意思表示だと思う。そうなら、
だろう。
順番を考慮してまとめると:
[追記]二番目の前提に、!_MFC_VER を追加。MSVC Express Editionだと、MSCではあるが、MFCが付いてない。そのときは、NO_MFCをセットすべき。[/追記]
その他
あと、開発中かリリースかはNDEBUGだけで判断。ユーザー定義の定数は出来るだけ作りたくない。
開発中にしか意味のないソースがあったなら、全体を #ifndef NDEBUG …… #endif しておいて、リリース時には空っぽになるようにしておくといいかも。