可変引数マクロ

:GNU Cにおいて、マクロは、例えば、などのパラメータの可変数、同じ機能を受け入れることができる
\の#define pr_debug(FMT、アルギニン...)
のprintk(KERN_DEBUG FMT、アルギニン##)



マクロ変数パラメータ(可変長マクロ)と可変パラメータ表を渡し
、次のような、関数内の変数パラメータリストの使用に精通していることがあります
ボイドのprintf(定数文字*形式、...);

最近まで、実際の関数内の唯一の変数パラメータリストやアプリケーションが使用することはできませんマクロインチ

あなたは様々なパラメータテーブルマクロを持つことができます使用することができますので、C99コンパイラの標準は最終的に、それはあなたがマクロ変数パラメータ(可変引数マクロ)を定義することができ、このような状況を変更しました。マクロなどの可変パラメータは、次のようになります。

デバッグ(...)のprintfの#define(__ VA_ARGS__)

デフォルト数は、パラメータリストの変化を表すことができます。__VA_ARGS__マクロに渡されたパラメータを予約名を使用してください。あなたはマクロ展開を呼び出すと、実際のパラメータは、()Aをprintfのために渡されます。:例えば

、デバッグ( "Y D =%の\のN-"、Y)

マクロプロセッサが置き換えられます呼び出します

のprintf( "%のD = Y \ N-"、Y);

デバッグ()は可変パラメータであるからですマクロは、すべてに渡すことができるパラメータの数が異なる呼び出し:

デバッグ(「テスト」); //パラメータ

可変パラメータマクロが正式にC ++ ANSI / ISOによってサポートされていません。したがって、あなたはそれがこの技術をサポートしているかどうかを確認するために、あなたのコンパイラを確認する必要があります。



可変パラメータGCCおよびC99マクロ、印刷デバッグ情報より簡単で


:変数パラメータの事前定義マクロgccは本当に使いやすいです提供
の#ifdef DEBUGの
に#define DbgPrint(フォーマット、引数...)の\
のfprintf(stderrに、フォーマット、##引数)
の#else
の#define dbgPrint(フォーマット、引数...)
#endifの
ように定義された後、コードはdbgPrintで使用することができ、例えばdbgprint( "AAA%のS"、 __FILE__)。em11:私は、この機能の比較クールを感じる

:次はC99の方法で
の#define dgbmsg(FMT、...)の\
のprintf(FMT、__ VA_ARGS__)


新しいC99の仕様は、マクロ変数のパラメータサポートし


、次のように具体的な使用を:

以下のプログラムでありますコード:

の#include <STDARG.H>書式#include <stdio.hに>

に#define LOGSTRINGS(FM、...)のprintf(FM、__ VA_ARGS__)

int型のmain(){LOGSTRINGS( "こんにちは、%のD"、10);リターン0;}

が、今唯一のgccをサポートしているようです。


'##の指示でマクロ変数パラメータ


可変パラメータ(引数の可変数を持つマクロをマクロ )
ISO C規格1999年版では、マクロと同じ機能は、可変パラメータで定義することができます。構文は、マクロ構文と機能に似ています。ここでの例である:

の#defineデバッグ(フォーマット、...)関数fprintf(stderrに、フォーマット、において__VA_ARGS__)

ここでは、 '...'可変パラメータを意味します。そのようなマクロは、それが呼び出され(と呼ぶ「...」)右括弧まで最後までの任意のカンマを含むゼロ個以上のシンボルを表しています。呼び出されると、マクロ本体(マクロボディ)で、それは__VA_ARGS__識別子内にセットシンボル列を置き換えます。詳しい情報は、CPPマニュアルを見つけることができます。

GCCは常に、それはあなたが他の引数と同様に、可変パラメータ名を付けることができ許さ異なる構文を使用して、複雑なマクロをサポートしてきました。例えば、以下の例:

の#defineデバッグ(フォーマット、引数...)関数fprintf(stderrに、フォーマット、引数)

。これは、先に引用ISO Cマクロ定義が正確に同じであるの一例であり、そのように読みやすく書くと簡単に説明しました。

GNU CPP両方の形式は、上記のフォーマットを定義サポートするために2話のより複雑なマクロ展開があります。

標準Cでは、変数のパラメータを省略することはできませんが、それに空の引数を渡すことができます。コンマは、文字列の後がないのでたとえば、ISO Cレーンで次のマクロ呼び出しは違法です:

デバッグ(「メッセージA」)

この場合、GNU CPPは、あなたが完全に可変パラメータを無視することができます。上記の例では、コンパイラは、依然として、問題を(文句)が余分なコンマを有することになる文字列が続くマクロ展開、なぜなら。

この問題を解決するために、CPPは、特別な「##」アクションを使用しています。フォーマットを書く:

の#defineデバッグ(フォーマット、...)関数fprintf(stderrに、フォーマット、##で__VA_ARGS__)

変数パラメータがNULLか無視であればここでは、「##」アクションを削除(プリプロセッサを)プリプロセッサますそれは、コンマの前に出ています。あなたには、いくつかの変数パラメータを提供し、GNU CPPが動作するマクロを呼び出す場合は、これらの可変パラメータの後ろにカンマを入れます。他の貼り付けマクロ引数と同じように、これらの引数は、マクロ展開ではありません。






引数のマクロ変数番号を記入する方法


の一つ一般的な技術は、() ``パラメータの定義とマクロ展開でマクロ呼び出しのパラメータはprintfのために同様の機能として、全体の時間になったと括弧で囲まれた別のを使用することですパラメータリスト。
DEBUG(引数)(のprintf( "DEBUG:")、printfの引数)を#defineし

(= N-0!)のIF DEBUG(()、N- "D%\ N-のn-である");
呼び出し元という明らかな欠点私たちは。括弧の余分なペアを使用するために覚えておく必要があります

gccは関数のようなマクロは、パラメータの可変数を受け入れることを可能にする拡張機能を持っている。しかし、これは標準ではありません。別の可能な解決策は、パラメータの数に基づいて、複数のマクロを使用することです(そのようなコンマのDEBUG1、DEBUG2、等)、又はトリックプレイ:

DEBUG #defineする(引数)を(のprintf( "DEBUG")のprintf(引数))
の#define _、

DEBUG( "%のD = I" _ I);
C99は、機能マクロのパラメータの数が可変のための正式なサポートを導入しました。(可変パラメータ関数定義のように)マクロ``プロトタイプ「プラス記号...の終わりには、マクロ定義疑似マクロ__VA_ARGS__呼び出しは、変数パラメータで置き換えられます。

最後に、あなたが常にできますあなたは本当の機能が明確に定義された変数のパラメータを受け入れることで使用できる

マクロを交換する必要がある場合などの#defineのprintf myprintfとして、機能と非機能マクロを使用し、。

ます。https://my.oschina.net/dake/blog/196782で再現

おすすめ

転載: blog.csdn.net/weixin_34217711/article/details/91586286