[英]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.