LoginSignup
12
10

More than 5 years have passed since last update.

VC++が勝手にキーワードnear, farをマクロ定義している? ソースをいじらずに回避する離れ業

Last updated at Posted at 2015-01-23

古い話とひどい話

MS-DOSやWin16のプログラミングをしたことがある方ならnearポインタ、farポインタという言葉を聞いたことがあることと思います。
8086互換の16ビットアドレッシングがnearポインタ、80286以降で使えるようになった32ビット(というよりは16+16ビット)アドレッシングがfarポインタで、DOSとかWin16のC/C++開発環境ではこれらを使い分けるためにnear, farというキーワードが定義されていました。

そして信じがたいことに、これらのキーワードは最新のVisual C++にも定義されています。

minwindef.h
#define near
#define far

すると何が起こるかといいますと、コンパイラ汎用C/C++で作られていたはずのOSSが変数名とかでnear, farを使っているとそこでコンパイルエラーです。まったく、ひどい話と言うほかない。
(そして、コメント欄でも言及されているmin, maxマクロと違って、コンパイルオプションで無効化する方法さえ用意されていません)

まあ、ソースをいじって near, far あたりのトークンを別の単語に書き換えてやれば通るのですが、サブモジュールリポジトリを汚したくもない。さていかがするか。

離れ業

windows.h を乗っ取ります。乗っ取るってどういうことか。

1. #include <windows.h> をニセwindows.hへ誘導する
2. ニセwindows.hでは本物のwindows.hをインクルードして直後にnear,farを殺す

ポイントは、どうやって ニセwindows.hの中で本物のwindows.hを呼ぶかです。だって、 #include <windows.h> なんて記述したら自分自身を呼んでしまって無限再帰参照でコンパイルエラーですからね。確実に本物を呼ぶ方法が必要なのです。
どうするか。Windows SDKの本物が …\include\um\ というディレクトリに置いてあるのを利用しましょう。#include <../um/windows.h> と記述して参照します。これは表技感あふれます。

まとめますと、インクルード検索対象ディレクトリにこんな windows.h を置くことになります。

windows.h
#pragma once
#include <../um/windows.h>
#undef near
#undef far
12
10
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10