問題の歴史
パラメータを持つマクロは、Cのプリプロセッサの重要な部分であり、繰り返されるコードの断片を迅速に挿入し、デバッグを簡素化するために登場しました。これは、小さな関数、インライン化、最適化のために使用されます。
問題
マクロは型をチェックせず、単純なテキスト置換以外の完全な置換を行いません。カッコが欠如していたり、副作用のある式が置き換えられることでエラーが発生します。
解決策
パラメータとマクロの定義をカッコで囲み、副作用のない引数を避け、より複雑なケースにはインライン関数を使用します。
コード例:
#define MAX(a, b) ((a) > (b) ? (a) : (b)) int x = 5, y = 10; int z = MAX(x++, y++); // 危険な呼び出し!
主な特徴:
マクロは常に関数のようにコードを完全に置き換えますか?
いいえ!マクロはあくまでコンパイル前のテキスト置換であり、引数が副作用のある式の場合、関数とは異なる動作をすることがあります。
マクロのパラメータとして任意の呼び出し(++や--を含む)を使用できますか?
これは非常に危険です。パラメータがマクロ内で複数回使用される場合、副作用が何度も発生します。
コード例:
// この呼び出しはxまたはyを1以上増加させます MAX(x++, y++)
マクロの定義においてカッコを正しく入れるには?
マクロ内のパラメータと式をカッコで囲み、他の式内での呼び出し時に結合の誤りを避けます。
会社では長年にわたりマクロ#define SQUARE(x) xxが定義されており、SQUARE(a+1)のような式に使用されていました。予期しないエラーが発生しました:式はa+1a+1として展開され、(a+1)*(a+1)とは異なります。
利点:
マクロSQUAREは完全なカッコを使用して書かれました: #define SQUARE(x) ((x)*(x))。その使用は標準化され文書化されています。
利点: