129

インライン関数とプリプロセッサ マクロの違いは何ですか?

4

14 に答える 14

137

プリプロセッサ マクロは、コードに適用される単なる置換パターンです。これらは、コンパイルが開始される前に展開に置き換えられるため、コードのほぼどこでも使用できます。

インライン関数は、本体が呼び出しサイトに直接注入される実際の関数です。これらは、関数呼び出しが適切な場合にのみ使用できます。

ここで、関数のようなコンテキストでマクロとインライン関数を使用する限り、次の点に注意してください。

  • マクロはタイプ セーフではなく、構文的に正しいかどうかに関係なく展開できます。コンパイル フェーズでは、マクロ展開の問題に起因するエラーが報告されます。
  • 予期しないコンテキストでマクロを使用すると、問題が発生する可能性があります
  • マクロは、他のマクロを展開できるという点でより柔軟ですが、インライン関数は必ずしもこれを行うわけではありません。
  • 入力式はパターン内のどこにでもコピーされるため、マクロは展開によって副作用を引き起こす可能性があります。
  • インライン関数は常にインライン化されるとは限りません。一部のコンパイラは、リリース ビルドでのみインライン化を行うか、インライン化するように特別に構成されている場合にのみ行います。また、場合によってはインライン化できない場合があります。
  • インライン関数は変数 (特に静的なもの) にスコープを提供できます。プリプロセッサ マクロはコード ブロック {...} でのみこれを行うことができ、静的変数はまったく同じように動作しません。
于 2009-07-16T13:33:32.173 に答える
17

インライン関数はコンパイラによって展開されますが、マクロは単なるテキスト置換であるプリプロセッサによって展開されます。

したがって、

  • 型チェックは関数呼び出し中に行われますが、マクロ呼び出し中は型チェックはありません。

  • 引数や演算順序の再評価により、マクロ展開時に望ましくない結果や非効率が発生する可能性があります。例えば:

    #define MAX(a,b) ((a)>(b) ? (a) : (b))
    int i = 5, j = MAX(i++, 0);
    

    結果として

    int i = 5, j = ((i++)>(0) ? (i++) : (0));
    
  • マクロ引数は、マクロ展開の前に評価されません

     #include <stdio.h>
     #define MUL(a, b) a*b
    
     int main()
     {
         // The macro is expended as 2 + 3 * 3 + 5, not as 5*8
         printf("%d", MUL(2+3, 3+5));
         return 0;
     }
     // Output: 16
    
  • 関数の場合のように、return キーワードをマクロで使用して値を返すことはできません。

  • インライン関数はオーバーロードできます。

  • マクロに渡されたトークンは、トークン貼り付け##演算子と呼ばれる演算子を使用して連結できます。

  • マクロは通常、コードの再利用に使用されます。インライン関数は、関数呼び出し中の時間オーバーヘッド (余分な時間) を排除するために使用されます (サブルーチンへのジャンプを回避します)。

于 2014-10-05T10:52:50.850 に答える
13

主な違いは型チェックです。コンパイラは、入力値として渡すものが関数に渡すことができる型であるかどうかをチェックします。これはプリプロセッサ マクロには当てはまりません。マクロは型チェックの前に展開されるため、深刻で検出が困難なバグが発生する可能性があります。

ここでは、概説されている他のいくつかのあまり明白でない点を示します。

于 2009-07-16T13:27:34.070 に答える
8

マクロは名前空間を無視しています。そして、それは彼らを悪にします。

于 2009-07-16T13:34:01.067 に答える
3

インライン関数はマクロに似ています (コンパイル時の呼び出しの時点で関数コードが展開されるため)。インライン関数はコンパイラによって解析されますが、マクロはプリプロセッサによって展開されます。その結果、いくつかの重要な違いがあります。

  • インライン関数は、通常の関数に適用されるタイプ セーフのすべてのプロトコルに従います。
  • インライン関数は、関数宣言に inline キーワードが含まれていることを除いて、他の関数と同じ構文を使用して指定されます。
  • インライン関数に引数として渡される式は、1 回評価されます。
  • 場合によっては、引数としてマクロに渡される式が複数回評価されることがあります。 http://msdn.microsoft.com/en-us/library/bf6bf4cf.aspx

  • マクロはプリコンパイル時に展開されるため、デバッグには使用できませんが、インライン関数は使用できます。

--良い記事: http://www.codeguru.com/forum/showpost.php?p=1093923&postcount=1

;

于 2009-07-16T14:11:48.193 に答える
2

インライン関数は値のセマンティクスを維持しますが、プリプロセッサ マクロは構文をコピーするだけです。引数を複数回使用すると、プリプロセッサ マクロで非常に微妙なバグが発生する可能性があります。インライン関数にはこの問題はありません。

于 2009-07-16T13:30:00.510 に答える
1

インライン関数は、構文的には通常の関数と同じように動作し、型の安全性と関数のローカル変数のスコープを提供し、メソッドの場合はクラス メンバーへのアクセスを提供します。また、インライン メソッドを呼び出すときは、プライベート/保護された制限に従う必要があります。

于 2009-07-16T13:29:14.487 に答える
0

コーディングの観点からは、インライン関数は関数のようなものです。したがって、インライン関数とマクロの違いは、関数とマクロの違いと同じです。

コンパイルの観点からは、インライン関数はマクロに似ています。呼び出されるのではなく、コードに直接挿入されます。

一般に、インライン関数は、マイナーな最適化が混在した通常の関数と見なす必要があります。また、ほとんどの最適化と同様に、実際に適用するかどうかを決定するのはコンパイラ次第です。多くの場合、コンパイラーは、さまざまな理由で、関数をインライン化しようとするプログラマーの試みを喜んで無視します。

于 2009-07-16T13:42:13.380 に答える