[英]What is the correct way to define this C macro?
#include <stdio.h>
#define ABS(a) (a) < 0 ? -(a) : (a)
int main(void)
{
printf("%d\n", ABS(-3) + 1);
return 0;
}
這段代碼片段來自Herbert Schildt的書,看起來它會產生輸出4
但實際上它打印3
。 為什么?
我如何解決它?
正確的方法是使用inline
函數,對於要支持的每種類型都使用_Generic
大小寫。 否則,你評估a
兩次。
代替它,您可以通過在宏中括起表達式來修復它。 這一直是防止這類問題的好主意。
#define ABS(a) ((a) < 0 ? -(a) : (a))
問題來自於X ? Y : Z + 1
X ? Y : Z + 1
表示X ? Y : (Z + 1)
X ? Y : (Z + 1)
。
擴展您的宏:
#define ABS(a) (a) < 0 ? -(a) : (a)
printf("%d\n", ABS(-3) + 1);
printf("%d\n", (-3) < 0 ? -(-3) : (-3) + 1); // you can get this with **gcc -E source.c
printf("%d\n", (-3) < 0 ? 3 : -2); //read about precedence to understand this step.
printf("%d\n", 3);
這是為什么要打印3
逐步解釋。 您需要使用適當的括號來修復它。
與函數不同,宏在遇到它們的地方展開。 因此在此代碼中
printf("%d\n", ABS(-3) + 1);
當遇到ABS(-3)時,它被擴展,即
printf("%d\n", (-3) < 0 ? -(-3) : (-3) + 1);
所以expressoin是真的, - ( - 3)被評估(在你的情況下)。 如果表達式被評估為假(例如),那么結果將是(-3)+1,即-2。
解決這個問題,而不是
#define ABS(a) (a) < 0 ? -(a) : (a)
寫
#define ABS(a) ((a) < 0 ? -(a) : (a))
修正括號#define ABS(a)(((a)<0)? - (a):( a))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.