9

C FAQ によると、Cでコードを「インライン化」するには、基本的に 3 つの実用的な方法があります。

#define MACRO(arg1, arg2) do { \
    /* declarations */ \
    stmt1;   \
    stmt2;   \
    /* ... */  \
    } while(0)    /* (no trailing ; ) */

また

#define FUNC(arg1, arg2) (expr1, expr2, expr3)

これを明確にするために、引数は式で使用され、カンマ演算子は最後の式の値を返します。

また

gcc の拡張としてサポートされ、c99 標準でinlineサポートされている宣言を使用します。

このdo { ... } while (0)方法は Linux カーネルで広く使用されていますが、私は他の 2 つの方法に遭遇したことはほとんどありません。

MAX や MIN のような単一ステートメントの関数ではなく、複数ステートメントの「関数」について具体的に言及しています。

それぞれの方法の長所と短所は何ですか? また、さまざまな状況でどちらか一方を選択するのはなぜですか?

4

3 に答える 3

16

マクロの特定の使用法、つまり「関数」として機能するマクロについて言えば、インライン関数では使用できないマクロの次の利点について言及します。

遅延引数評価。例えばこんなマクロ

#define SELECT(f, a, b) ((f) ? (a) : (b))

三項演算子の遅延引数評価プロパティを保持します。選択されたパラメーターのみが評価され、他のパラメーターは評価されません。単純なインライン関数の類似物は、事前に両方の引数を評価するため、余分な不要な作業が行われます。

コンテキストへのアクセス。マクロを使用して、「ローカル関数」に似たものを実装できます。つまり、ローカル変数と囲んでいる関数のパラメーターにアクセスできる反復的なコード片です。

型の独立性 (および型パラメーター)。マクロを使用すると、型に依存しない「関数」を記述できます (上記の例を参照)。また、型の依存関係を取り除くことができない場合は、型をパラメーターとしてマクロに渡すことができます。

私が長所として提示したマクロの上記の特性は、誤用されて重大な失敗につながる可能性があります (したがって、短所としても提示される可能性があります)。しかし、これは C の多くの言語機能について言えることです。

于 2009-10-15T11:13:06.607 に答える
5

inline キーワードを使用するメリットの 1 つは、関数プロトタイプを介して引数の型を確認できることです。マクロを使用すると、そのようなことは何も得られないため、マクロに間違ったタイプのものを入れると、奇妙なエラーが発生する可能性があります。(ただし、C++ のテンプレート エラーほどひどいものではありません。)

マクロを使用するメリットの 1 つは、連結や #arg を使用してマクロ引数を文字列に変換するなど、ファンキーなことを実行できることです。プリプロセッサ マクロを使用するもう 1 つの利点は、cpp を使用してどのように展開し、巻き戻すかを簡単に確認できることです。これは、これらのエラーをデバッグする方法です。

マクロ定義関数のもう 1 つの便利な点は、return必要に応じてステートメントを挿入して親​​関数を停止できることです。インライン関数では、値を返してから戻り値を確認する必要があります。

于 2009-10-15T10:28:18.917 に答える
0

いずれかの構成を使用することで私が見ることができる唯一の長所は、コードを高速化することです。

したがって、最速のコードを提供する方法を 1 つ選択してください。

それがすべて同じなら、私はそれがより読みやすいと思います

  1. 「標準」関数
  2. inline関数_
  3. #define ... do {} while(0)アプローチ_
  4. コンマで区切られた式を持つマクロ
于 2009-10-15T10:17:25.980 に答える