マクロを定義するプラグマ


99

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

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

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

ブーストソリューション(ウェーブ用に保存)があれば問題ありません。


5
間違いなくどちらでもない-#pragmasはCまたはC ++標準のどちらでも定義されていません。

プリプロセッサーは、たとえ実行したい特定の許可されたサブコマンドがそうでなくてもです。
パピー

@DeadMG:CとC ++の間には、多くの共通点があります。ほとんどの前処理は一般的ですが、使用されている言語標準(C89、C99、C ++、およびC ++ 0x FCD)によって、前処理の指定方法に大きな違いがあります。
James McNellis、2010年

2
@James McNellis:技術的には、ほとんどのCプログラムはC ++に移植可能であるという理由だけで、C ++プログラマーがその大部分を行うことはないため、真に一般的な機能は実現しません。2つの言語は実際にはあまり共通点がありません。
パピー

回答:


114

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
 ;

32
参考までに:MSVCには__pragma()プリプロセッサオペレーターがありますが、残念ながらC99の_Pragma()オペレーターとは少し異なります(C99は文字列リテラルを受け取り、MSVCは文字列にないトークンを受け取ります):msdn.microsoft.com/en-us/library/d9x1s805 .aspx
Michael Burr

15
@MichaelBurr MSVCは常に異なる必要がありますね。
トーマス

5

_Pragma( "argument")を使用して実行できる優れた点の1つは、それを使用して、次のようなコンパイラの問題を処理することです。

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

0

いいえ、それを行うポータブルな方法はありません。繰り返しになりますが、#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;    

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

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

ああ、私はあなたが実際にWeak_bとWeak_eをパラメーターを取るマクロとして定義する必要があると思うが、私はこの例のためだけに弱い定義を作成する方法についてのドキュメントを読みたくなかった。読者の練習問題として残しておきます。


-3

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

いいえ、プリプロセッサー・ステートメントをプリプロセッサー・ステートメントに入れることはできません。ただし、inline関数に組み込むことはできます。Cただし、これはタグを無効にします。


1
それをインライン関数に入れるとどうなるでしょうか?プリプロセッサディレクティブは、関数を認識できる前に処理されます。

2
C99にはがinlineあり、ほとんどの主要なC89実装にはいくつかのバリエーションがあります。
Chris Lutz

@Chrisあなたのコメントが私に向けられたと仮定して-あなたのポイントは-何ですか?

@ニール-いいえ、申し訳ありません。@sbiの最後の文に向けていました。
Chris Lutz

1
@Chris:ああ、inlineCがC ++から借りたもう1つのことも!:)
sbi
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.