我正在查看 IDE 中包含的 math.h header 。我看到以下代码是我不明白的语法。这是基本的东西,但有人可以向我解释这是如何工作的吗?

#define isgreater(x,y) \
          (__extension__ ({__typeof__(x) __x = (x); __typeof__(y) __y = (y); \
                           !isunordered(__x,__y) && (__x > __y);}))

例如,当您以双下划线开头时它会做什么,例如:__typeof这是为了允许未定义的尺寸吗?所以这个宏可以取不同大小的值?

斜线只是为了跨越源代码中的换行符吗?
__extension__ 有什么作用?

谢谢

最佳答案

您正在看到一些编译器扩展的使用:

  • __typeof__ 是一个 GCC 扩展,它可以让你获取变量的类型(并在变量声明中使用它);它在那里,以便宏可以处理 xy 的任何类型。
  • 第二个 GCC 扩展将 ({ ... }) 转换为一个表达式,该表达式的计算结果为其中最后一条语句的值;这让您可以在此块中声明变量,这是为了避免对两个操作数 xy 求值两次。 xy 的结果(可能类似于 i++,您不想计算两次)存储在两个临时变量 __x__y 中,然后使用这两个临时变量代替 xy 以避免双重评估。
  • __extension__ 是一个扩展,它可以抑制您在使用上述扩展时会收到的警告。

  • 是的,\ 只是使宏的定义跨越多行(\ 将行连接在一起,并且在编译过程的早期完成,甚至在查看宏和预处理器定义之前)。

    这个繁琐的重点是避免对 xy 求值两次。如果你做了
    bool g = isgreater(x++, y++);
    

    你没有使用那个技巧,你会得到
    bool g = !isunordered(x++, y++) && (x++ > y++);
    

    这会导致 xy 每次增加两次,而不是像您预期的那样只增加一次。相反,通过这个技巧,你会得到类似的东西(为临时变量使用更好的名字)
    int tmpx = x++;
    int tmpy = y++;
    bool g = !isunordered(tmpx, tmpy) && (tmpx > tmpy);
    

    (如果 xy 是整数)这是正确的并且避免了双重递增。这也适用于其他事情,例如函数调用:
    isgreater(launch_missiles(3), launch_missiles(4));
    

    如果没有这个技巧,你最终会发射 14 枚导弹而不是 7 枚,这将是灾难性的。

    关于c - 基本的 C 头文件语法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9776024/

    10-11 22:37