web-dev-qa-db-ja.com

インライン関数とマクロ関数

可能性のある複製:
インライン関数とプリプロセッサマクロ

インライン関数とマクロ関数の違いを知りたいです。

1)インライン関数はマクロ関数と同じですか?

2)どちらも呼び出されないことを知っていますが、コンパイル段階でコードに置き換えられます。ではありません?

3)違いがある場合、それを指定してもらえますか?

16
MOHAMED

インラインは、関数の呼び出しを関数の本体に置き換えますが、インラインは無視できるコンパイラーに対するrequestですいくつかのフラグをコンパイラに渡し、インラインを強制するか、gccでalways_inline属性を使用します)。

一方、マクロは、コンパイル前にpreprocessorによって展開されるため、テキスト置換のようになります。また、マクロは型チェックされず、インライン関数は。 wiki には比較があります。

完全を期すために、gccの__typeof__たとえば、次のコードはほぼ同一のコードを生成し、誤ったタイプで使用すると警告が発生します。

#define max(a,b) \
  ({ __typeof__ (a) _a = (a); \
      __typeof__ (b) _b = (b); \
    _a > _b ? _a : _b; })

__attribute__((always_inline)) int max(int a, int b) {
   return (a > b ? a : b);
}

注:型なしマクロが必要な場合があります。たとえば、キャストを使用せずに thash がマクロを使用してC構造体をハッシュ可能にする方法を確認してください。

24
iabdalkader

1)いいえ.

2)Cのマクロは、展開された単なるテキストですbeforeコンパイラはソースコードを処理します。 inlineキーワードは、呼び出しスタックを設定する必要なく関数をインラインに配置できるというコンパイラーへのヒントとして使用されます。

したがって、たとえば、次の2つのコードスニペット(最初にマクロ、次にインライン関数)を取得したとしましょう。

#define MAX(x,y)     (x > y ? x : y)

そして

inline int max(int x, int y) { return x > y ? x : y; }

プリプロセッサがコード内で次の呼び出しを見つけたとき:

int highest = MAX (var_1, var_2);

それを置き換えます

int highest = (var_1 > var_2 ? var_1 : var_2);

上記は、コンパイルプロセス中にコンパイラが最終的に取得するものです。したがって、MAX(x、y)で定義されるスニペットは、MAX(var_1、var_2)のreplacementです。コンパイラが関数呼び出しを見つけたとき

int highest = max (var_1, var_2);

次に、関数「max」が呼び出されます。コンパイラーは「インライン」ヒントを無視して、関数の呼び出しを通常の呼び出しスタックに通すだけで、関数のコードをその場所に単に配置するので、通常の方法で呼び出されると想定する必要があります。遭遇しました。

マクロに関する最後の警告:これはすべてテキストの置換であり、コードの置換ではないため、次のような場合:

int highest = MAX (v1++, v2++);

プリプロセッサはそれを次のように展開します。

int highest = (v1++ > v2++ ? v1++ : v2++);

これはおそらくあなたが意図したものではありません。

19
Lelanthran

マクロは、プリプロセッサによって(実際のcompileの前に)置換される宣言です。これらはまったく関数ではありません。実際のcompileフェーズが始まる前に、マクロはなくなっており、残っているのはそれらの展開(何も展開しないことを含む)だけです。

実際、インライン関数は、言語に準拠しています関数で、スコープルール、変数宣言、論理構造(ループなど)などがあります。インライン関数は、マクロのようにプリコンパイルステップで展開されません。通常のコードと同様にコンパイル済みですが、(より良い用語がないため)コンパイル済みコードに挿入し、必要に応じて最適化できます。

6
WhozCraig

inlinemacroの定義と同じではありません。マクロは前処理されますが、インラインはコンパイラーが関数の全体を呼び出す場所に配置するための単なる指示です。

関数定義の前にインラインキーワードを置くことは単なる指示または要求であり、コンパイラはその関数をインラインにするか通常のままにするかを自由に選択できます

マクロ置換:preprocessing phase(つまり、コンパイル前)

- 入力ファイル test.clinuxの結果ファイルtest.i

インライン置換:compilation phase

1
Omkant