[解決済み] GCCの##__VA_ARGS__トリックの標準的な代替手段?
質問
があります。 よく知られている 問題 C99で可変長マクロの引数が空だったこと。
の例です。
#define FOO(...) printf(__VA_ARGS__)
#define BAR(fmt, ...) printf(fmt, __VA_ARGS__)
FOO("this works fine");
BAR("this breaks!");
の使用は
BAR()
に展開されるため、C99規格によれば確かに不正確である。
printf("this breaks!",);
最後のコンマに注意 - 実行不可能です。
いくつかのコンパイラ(例:Visual Studio 2010)は、この末尾のカンマを静かに取り除いてくれます。他のコンパイラ(例:GCC)は
##
の前にある
__VA_ARGS__
というように。
#define BAR(fmt, ...) printf(fmt, ##__VA_ARGS__)
しかし、この動作を得るための標準に準拠した方法はあるのでしょうか? もしかしたら、複数のマクロを使うとか?
今現在は
##
のバージョンは、(少なくとも私のプラットフォームでは)かなりよくサポートされているようですが、私はむしろ標準に準拠したソリューションを使いたいと思っています。
先取りです。小さな関数を書けばいいのは分かっているのですが。マクロを使ってやってみたいんです。
編集 : BAR()を使いたくなるような例を(簡単ですが)挙げておきます。
#define BAR(fmt, ...) printf(fmt "\n", ##__VA_ARGS__)
BAR("here is a log message");
BAR("here is a log message with a param: %d", 42);
これは、BAR() のロギングステートメントに自動的に改行を追加し、次のように仮定します。
fmt
は常にダブルクォートされたC文字列である。これは、改行を別の printf() として表示しません。これは、ロギングがラインバッファリングされ、複数のソースから非同期に送られてくる場合に有利です。
解決するには?
GCC の
,##__VA_ARGS__
で説明されているように、可変個数マクロに渡すことができる引数の数にハードコードされた上限を受け入れることができるのであれば、拡張機能を使用することができます。
この質問に対するリチャード・ハンセン氏の回答
. clangとiccはこのGCC拡張を採用していますが、MSVCは採用していません。
2001年に私は標準化のためのGCC拡張機能(および関連する拡張機能で
__VA_ARGS__
にあるように、残りのパラメータは
ドキュメントN976
しかし、委員会からは何の反応もなく、誰かが読んだかどうかもわからない。 2016年に再び提案されたのは
N2023
その提案がどうなっているのかご存知の方は、ぜひコメントで教えてください。
関連
-
構造体の配列--[エラー] '['トークンの前に一次式があることが予想される
-
g++が内部・外部コマンドソリューションとして認識されない、MinGWを初めて使うときの落とし穴
-
Cエラー [エラー] 代入_Ashesの左オペランドにlvalueが必要です-プログラマーズ・シークレット
-
[解決済み] PTHREAD_MUTEX_INITIALIZER vs pthread_mutex_init ( &mutex, param )
-
[解決済み] C言語でchar配列をコピーする方法は?
-
[解決済み] ⑭と⑯は何のためにあるのですか?
-
[解決済み] Linux Socket write() によるBad File Descriptor C
-
[解決済み] while ( !feof (file) ) 」は、なぜいつも間違っているのですか?
-
[解決済み] LD_PRELOADのトリックとは何ですか?
-
[解決済み】標準ライブラリを使ってアライメントされたメモリのみを割り当てるには?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[C] Error [Error] 代入の左オペランドとして lvalue が必要です。
-
ポインタ定数および定数ポインタ
-
未定義の `__isoc99_sscanf' への参照
-
[解決済み] 初期化でポインタ対象の型から修飾語を捨てる
-
[解決済み] Xcode - 警告。C99 では関数の暗黙の宣言は無効です。
-
[解決済み] なぜmemsetではなくbzeroを使用するのですか?
-
[解決済み] C - Setデータ構造を実装するには?
-
[解決済み] C言語における「static」の意味とは?
-
[解決済み] mallocとcallocの違い?
-
[解決済み] C言語標準に準拠した構造体の初期化方法