web-dev-qa-db-ja.com

マクロ定義のプラグマ

マクロにプラグマステートメントを他のステートメントと埋め込む方法はありますか?

私は次のようなことを達成しようとしています:

#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type_(int handle);                  \
    void delete_ ## type(int handle);                                                \
    #pragma weak delete_ ## type_ = delete_ ## type

ブーストソリューション(waveを保存)があればそれでも構いません。

91
Anycorn

C99またはc ++ 0xを使用している場合、次のように使用されるプラグマ演算子があります。

_Pragma("argument")

これは

#pragma argument

マクロで使用できることを除いて(c99標準のセクション6.10.9、またはc ++ 0x最終委員会ドラフトの16.9を参照)

例えば、

#define STRINGIFY(a) #a
#define DEFINE_DELETE_OBJECT(type)                      \
    void delete_ ## type ## _(int handle);                  \
    void delete_ ## type(int handle);                   \
    _Pragma( STRINGIFY( weak delete_ ## type ## _ = delete_ ## type) )
DEFINE_DELETE_OBJECT(foo);

gcc -Eに入れると、

void delete_foo_(int handle); void delete_foo(int handle);
#pragma weak delete_foo_ = delete_foo
 ;
105
Scott Wales

_Pragma( "argument")でできることの1つは、次のようなコンパイラの問題に対処するために使用することです。

#ifdef _MSC_VER
#define DUMMY_PRAGMA _Pragma("argument")
#else
#define DUMMY_PRAGMA _Pragma("alt argument")
#endif
4
John Thomas

いいえ、ポータブルな方法はありません。この場合も、#pragmaを使用する移植可能な方法はまったくありません。このため、多くのC/C++コンパイラはプラグマのようなことを行う独自のメソッドを定義し、多くの場合マクロに埋め込むことができますが、コンパイラごとに異なるマクロ定義が必要です。あなたがその道を進んで進んでいるなら、あなたはしばしばこのようなことをすることになります:

#if defined(COMPILER_GCC)
#define Weak_b
#define Weak_e __attribute__((weak))
#Elif defined(COMPILER_FOO)
#define Weak_b __Is_Weak
#define Weak_e
#endif

#define DEFINE_DELETE_OBJECT(type)                      \
    Weak_b void delete_ ## type_(int handle) Weak_e;    \
    Weak_b void delete_ ## type(int handle)  Weak_e;    

明らかでない場合は、Weak_bおよびWeak_eは、GCCのような一部のコンパイラは属性を型シグネチャの補遺として追加し、一部のコンパイラはMSCのようにプレフィックスとして追加します(または少なくともそれを追加するため) MSCを使用してから数年が経ちました。ブラケットコンストラクタを使用すると、型シグネチャ全体をコンパイラコンストラクトに渡す必要がある場合でも、常に機能するものを定義できます。

もちろん、必要な属性なしでこれをコンパイラに移植しようとすると、マクロを何も展開せずに、コードが実行されることを望みます。純粋に警告または最適化プラグマの場合、これは可能性があります。他のケースでは、それほどではありません。

ああ、私はあなたが実際にパラメータを取るマクロとしてWeak_bとWeak_eを定義する必要があると思いますが、この例のためだけに弱い定義を作成する方法についてドキュメントを読むつもりはありませんでした。これは読者の演習として残しておきます。

0
swestrup