繁体   English   中英

定义此C宏的正确方法是什么?

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM