我正在查看 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 扩展,它可以让你获取变量的类型(并在变量声明中使用它);它在那里,以便宏可以处理 x
和 y
的任何类型。 ({ ... })
转换为一个表达式,该表达式的计算结果为其中最后一条语句的值;这让您可以在此块中声明变量,这是为了避免对两个操作数 x
和 y
求值两次。 x
和 y
的结果(可能类似于 i++
,您不想计算两次)存储在两个临时变量 __x
和 __y
中,然后使用这两个临时变量代替 x
和 y
以避免双重评估。 __extension__
是一个扩展,它可以抑制您在使用上述扩展时会收到的警告。 是的,
\
只是使宏的定义跨越多行(\
将行连接在一起,并且在编译过程的早期完成,甚至在查看宏和预处理器定义之前)。这个繁琐的重点是避免对
x
和 y
求值两次。如果你做了bool g = isgreater(x++, y++);
你没有使用那个技巧,你会得到
bool g = !isunordered(x++, y++) && (x++ > y++);
这会导致
x
和 y
每次增加两次,而不是像您预期的那样只增加一次。相反,通过这个技巧,你会得到类似的东西(为临时变量使用更好的名字)int tmpx = x++;
int tmpy = y++;
bool g = !isunordered(tmpx, tmpy) && (tmpx > tmpy);
(如果
x
和 y
是整数)这是正确的并且避免了双重递增。这也适用于其他事情,例如函数调用:isgreater(launch_missiles(3), launch_missiles(4));
如果没有这个技巧,你最终会发射 14 枚导弹而不是 7 枚,这将是灾难性的。
关于c - 基本的 C 头文件语法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/9776024/