このマクロ
#define abss(a) a >= 0 ? a : -a
確かに危険ですが、危険はあなたが思っているところにはありません。あなたの投稿からの表現
int c = abss(b);
完全に正常に動作します。ただし、式が単純な変数ではなく、計算が難しい関数である場合や、副作用のある式である場合はどうなるかを考えてみてください。例えば
int c = abss(long_calc(arg1, arg2));
また
int c = abss(ask_user("Enter a value"));
また
int c = abss(b++);
関数abss
である場合、3 つの呼び出しはすべて、予測可能な時間内に良好な結果を生成します。ただし、マクロは最初の呼び出しを呼び出しlong_calc
てからask_user
2 回実行し (再度プロンプトが表示されたときにユーザーが別の番号を入力するとどうなるでしょうか?)、後置インクリメントがb
2 回行われます。
さらに、この一見単純な式を考えてみてください。
int c = abss(b) + 123;
+
よりも優先順位が高いため? :
、結果の展開は次のようになります。
int c = b >= 0 ? b : -b + 123;
b
が正の場合は123
加算されないので、式の意味が大きく変わります!
この最後の欠点は、式を括弧で囲むことによって対処できます。また、次のように、各マクロ引数を括弧で囲む必要があります。
#define abss(a) ((a) >= 0 ? (a) : -(a))