何らかの理由で、私は一時的にいくつかのマクロをヘッダファイルで無効にする必要があり、#undef MACRONAME
はコードをコンパイルしますが、既存のマクロをundefします。C/C++でマクロ展開を一時的に無効にするにはどうすればよいですか?
無効にする方法はありますか?
マクロの値が分からず、クロスコンパイラソリューション(少なくともGCCとMSVCでは動作するはずです)を探しています。
何らかの理由で、私は一時的にいくつかのマクロをヘッダファイルで無効にする必要があり、#undef MACRONAME
はコードをコンパイルしますが、既存のマクロをundefします。C/C++でマクロ展開を一時的に無効にするにはどうすればよいですか?
無効にする方法はありますか?
マクロの値が分からず、クロスコンパイラソリューション(少なくともGCCとMSVCでは動作するはずです)を探しています。
MSVCでは、Microsoft Windowsコンパイラとの互換性のためにpush_macro
プラグマ、GCC supportsを使用できます。
#pragma push_macro("MACRONAME")
#undef MACRONAME
// some actions
#pragma pop_macro("MACRONAME")
それが存在することを知ってうれしい、と良い答えが、それは恐ろしいです。 – Novelocrat
これは、人々が*マクロが悪い*のようなことを私たちに伝え続ける理由です。遅かれ早かれ、ある人が何かばかげたことをする 'new'というマクロを作成しようとしています... –
@JohnLeidegrenまあ、今半分です。 [**悪意のある "悪"マクロの例**](http://stackoverflow.com/q/18167990/319204)。 – TheCodeArtist
スタンダードC(C89、C99またはC11)で定義された機能だけを使用すると、「無効」メカニズムは#undef
です。
「再有効化」メカニズムがないという問題があります。次いで、;それは任意のtypedefまたは列挙宣言を含まないようにマクロ定義を含むヘッダファイル(関数と変数の宣言を繰り返すことができ、これらを繰り返すことができない)に構成されている場合に他の人が、指摘したように
#undef
マクロを有効にしてマクロを使用せずに必要な処理を行った後、再組み込みに対する保護を定義していない可能性があります。
マクロがヘッダーに定義されていない場合は、コードをリファクタリングしてヘッダーに挿入するまでスタックされません。
マクロが機能的なマクロであり、オブジェクトのようなマクロでない場合、他のトリックも利用できます。
#define nonsense(a, b) b /\= a
int (nonsense)(int a, int b)
{
return (a > b) ? a : b;
}
機能nonsense()
は、その直前のマクロにもかかわらず、細かい定義されます。これは、マクロの呼び出し(関数のようなマクロの場合)の直後に、かっこ(空白を入れたり、コメントを含む可能性があります)を付ける必要があるからです。関数定義行では、 'ナンセンス'の後のトークンは閉じ括弧であるため、nonsense
マクロの呼び出しではありません。
マクロは引数なしのオブジェクトのようなマクロされていた、トリックは動作しませんが:
#define nonsense min
int (nonsense)(int a, int b)
{
// Think about it - what is the function really called?
return (a > b) ? a : b;
}
このコードはmin
と呼ばれる偽の関数を定義し、無意味です。マクロからの保護はありません。
これは、標準が「実装」のために予約されている名前空間を慎重に定義する理由の1つです。インプリメンテーションは、望むか必要なあらゆる目的のために、その名前が実装に予約されていれば、望むまたは必要とする任意のタイプ(機能的またはオブジェクト的)のマクロを定義することができます。実装のサービスのコンシューマーとして、実装に予約されている名前を使用または定義しようとする場合は、コードがおそらくは遅かれ早かれ破綻する可能性があることを認識していなければなりません。実装。
'(ナンセンス)'の回避策のUpvote。驚くばかり! –
マクロはいくつかのヘッダーファイルから来ているので、その値にアクセスする必要があります。その後、のような何かを行うことができます
#include <foo.h> // declares macro FOO
// Do things with FOO
#undef FOO
// do things without FOO
#include <foo.h> // reenable FOO
あなたのヘッダーは、これらの線に沿って設計されなければならない
#ifndef FOO
#define FOO do_something(x,y)
#endif
そのヘッダーファイルで有効/無効にしているマクロ以外のものがないことを確認してください。そうしないと、再宣言に問題が発生します。 –
また、 '
ヘッダファイルを再組み込みすると、ヘッダファイルがこのように使用するよう特別に設計されていない限り、他の問題が発生する可能性があります。 –
EDIT:
あなたはそれが簡単だと思うことがあります。
#ifdef macro
#define DISABLED_macro macro
#undef macro
#endif
// do what you want with macro
#ifdef DISABLED_macro
#define macro DISABLED_macro
#endif
しかし、そうではありません(次の例のようにes)!元のヘッダの再を含むマクロに#undef
を使用
#include <iostream>
#include <limits>
#include <windows.h>
#ifdef max
#define DISABLED_max max
#undef max
#endif
int main()
{
std::cout << std::numeric_limits<unsigned long>::max() << std::endl;
#ifdef DISABLED_max
#define max DISABLED_max
#endif
std::cout << max(15,3) << std::endl; // error C3861: "max": identifier not found
return 0;
}
があるため、ヘッダーガードの、も動作する可能性はありません。 残っているのはpush_macro/pop_macro #pragma
ディレクティブです。
#pragma push_macro("MACRO")
#undef MACRO
// do what you want
#pragma pop_macro("MACR")
40秒ほど私を打ち負かす... – KitsuneYMG
それ以外は動作しますか?マクロを「復元」しないので、「マクロ」に展開されます(欠落部分を追加したときに見えます)。 5月 - 完全な使用例ですか? – UncleBens
これは動作しません - ktsへの私のコメントを参照してください。 – Novelocrat
私はあなたが実際にこのマクロ混乱で終わった説得力のある理由があると思いますか?私はここで1つ考えることができませんでした... – sbi