掲示板システム
ホーム
アクセス解析
カテゴリ
ログアウト
#define定義されているマクロ名と関数名の衝突 (ID:68016)
名前
ホームページ(ブログ、Twitterなど)のURL (省略可)
本文
maruさん、ご回答ありがとうございます。 まだ疑問は残ります。私の説明が足りませんでした。 >ライブラリを使用している時にそのライブラリの定義を変更してはいけません。 もちろん定義は変更はしません。ネームスペースも使用しております。 今回は下記のようなコードが、 namespace Hoge { class MyDispatcher { public: void DispatchMessage(); // .... }; } // namespace Hoge end windows.hをインクルードしたために namespace Hoge { class MyDispatcher { public: void DispatchMessageW(); // .... }; } // namespace Hoge end のようにコンパイル前に置換されるのはどうかな?と思った次第です。 名前空間を使えば関数名の競合を防げるのは存じております。 ですが#defineによるマクロは名前空間に関係なく適用されてしまいます。 今回は上記のような予期せぬマクロ変換が起きていてもコンパイルができ、実行ファイルの動作にも影響がないので、なかなか変換に気が付きませんでした。 windows.hからインクルードされるwinuser.hで宣言されている::DispatchMessageというAPIに限らず、様々なAPIが#defineマクロで実際に呼び出す関数名を変換をしているようです。(UNICODEか否かで) このようなAPI群と同じ関数名を自分のプログラムで使いたい場合、マクロで変換されないよう#undefした場合にも問題が起こります。 下記のコードは極端な例だと思いますが、 #undef DispatchMessage namespace Hoge { class MyDispatcher { public: void DispatchMessage() { MSG msg; ::DispatchMessage(&msg) // WinAPIを呼び出す } // .... }; } // namespace Hoge end とすれば関数名はマクロ変換されずに済みますが、::DispatchMessageもマクロ変換されず呼び出せなくなってしまいます。(宣言があるのは::DispatchMessageA or DispatchMessageWなので) かといって、 #undef DispatchMessage namespace Hoge { class MyDispatcher { public: void DispatchMessage() { MSG msg; #ifdef UNICODE #define DispatchMessage DispatchMessageW #else #define DispatchMessage DispatchMessageA #endif // !UNICODE ::DispatchMessage(&msg) // WinAPIを呼び出す } // .... }; } // namespace Hoge end のように局所的にマクロを挿入するのも理不尽かと思う次第です。 アプリケーションがUNICODEを使うものと断定して直接DispatchMessageWを呼び出すのようにする手もありますが…。 書いてて思ったのですが、これはもうwindows.h等で宣言されているAPI関数(defineで変化される)と同じ名前の関数を使うのは避けた方が良いな、と思いました。 長文失礼いたしました。 なにかご意見ありましたらよろしくお願いします。
←解決時は質問者本人がここをチェックしてください。
更新する
戻る
掲示板システム
Copyright 2021 Takeshi Okamoto All Rights Reserved.