c - 最小/最大函数的无辜宏定义有什么问题?

标签 c macros

文件 windef.h 使用宏定义最小/最大函数如下:

#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))

It has been noted ,然而,这样的定义:

  1. 遭受双重评估。
  2. 类型不安全。

我不明白的是:

  1. 为什么/哪里有双重评估?
  2. 琐碎的重定义 __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); 有助于类型安全,为什么在这种情况下不进行双重评估?

最佳答案

Why/where is there double evaluation?

理解这一点的最简单方法是运行这段代码:

#include <stdio.h>

#define max(a,b) ((a)>(b)?(a):(b))

int f1 (void) 
{ 
  printf("%s executed.\n", __func__);
  return 1; 
}

int f2 (void) 
{ 
  printf("%s executed.\n", __func__);
  return 2; 
}

int main (void)
{
  printf("Max: %d", max(f1(), f2()) );
}

输出:

f1 executed.
f2 executed.
f2 executed.
Max: 2

函数 f2() 被调用了两次,因为宏参数 b 被计算了两次。


How does the trivial redefinition __typeof__ (a) _a = (a); __typeof__ (b) _b = (b); helps with type safety and why is it not double evaluation in this case?

因为该代码创建了两个临时变量并将评估结果存储在那里,每个变量一次。

请注意 __typeof__ 以及 ({ ... }) 语法不是标准的 C,应该避免使用。链接的已接受答案中的宏非常难看,我不推荐。

明智的解决方案是不使用宏而是使用函数:

static inline int max (int a, int b)
{
  return a > b ? a : b;
}

注意与困惑的宏相比,代码的可读性如何。

如果您出于某种未知原因必须使用宏,请坚​​持使用标准 C,如下所示:https://stackoverflow.com/a/30918240/584518

关于c - 最小/最大函数的无辜宏定义有什么问题?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47097148/

相关文章:

运行Mac应用程序的C程序

c++ - 在 Visual Studio 中从可变参数计数宏为常量参数计数宏提供输入

c - 如何在宏中使用 __func__

c++ - 递归宏传播的结果是什么?

c - 在 C 中的编译时查找 100 个结构的最大大小

c - 有关 C 中 `({});` 的更多信息?

c - While 循环响应 C 中的多个条件

无法使用 mbedtls 示例客户端连接到 https 服务器

在没有编译器生成序言/结尾和 RET 指令的情况下创建 C 函数?

C for 循环与 rolled out 循环有不同的效果