块返回值时调用的是什么?

我最近遇到了这个代码,这对我来说看起来不合法(但是gcc编译它)。 我不介意构造,因为它想要一个名字:

#define MAX(a,b) \ ({ \ typeof(a) _a = (a); \ typeof(b) _b = (b); \ (_a > _b) ? (_a) : (_b); \ }) 

显然,最后一个语句的值被返回为由命名空间限定的表达式的“值”。

编辑:谢谢你们的答案。 事实certificate,这是对称为Statement Expressions的普通C的扩展。

不是命名空间它是一个返回最多两个值的宏
\语句末尾用于追加多个语句并创建多行宏。

代码不是标准的C ++,但它在gcc中编译,因为它作为gcc编译器扩展支持。

好读:

声明表达:
复合语句是由大括号括起来的一系列语句。 在GNU C中,括号内的复合语句可能在所谓的Statement expression显示为Statement expression

  .--------------. V | >>-(--{----statement--;-+--}--)-------------------------------->< 

语句表达式的值是要在整个构造中出现的最后一个简单表达式的值。 如果最后一个语句不是表达式,则构造的类型为void且没有值。

注意:此摘录摘自IBM XL C / C ++ v7.0文档。

这称为语句表达式 ,是GCC的非标准扩展 。 它允许您将复合语句用作表达式,其值由复合语句中的最后一个表达式给出。

它用于避免类似函数的宏可能多次评估其参数的问题,如果这些评估具有副作用,则会产生意外行为。 仔细编写宏来评估ab一次。

在C ++中,你永远不需要做这样的事情 – 而是使用函数模板:

 template  T max(T const & a, T const & b) { return a > b ? a : b; } 

首先,它不是标准C ++,因为typeof是GCC对C ++的扩展。 还有另一个扩展名,在代码中使用了Statement Extension。

使用-pedantic选项编译代码,它将无法编译。

至于问题,它不是命名空间。 它只是一个宏,它最多给你两个值。

在这种情况下,{}运算符是一个“匿名范围运算符”(又名“词汇封闭”,“forms”和其他各种东西。它们被用来,有点类似于命名空间,以限制_a的范围并且_b在大括号内,所以它们不会与你可能拥有的其他变量相同的名称发生冲突。{braces}中定义的“auto”变量将在达到右大括号后被“销毁”;或者,在非本地转移,如“返回”或“longjmp”。但是,您不能可靠地使用“转到”来提升它们。

您可能只习惯在“if”,“do”,“while”和“for”运算符之后看到它们,但将其视为将多个语句“捆绑”到一个“槽”中的一种方式,就像你会运行多个语句作为“if”的“then”或“else”子句(其中,省略括号,你只有一个语句“slot”)

正如Mike Seymour指出的那样,({})操作是一个非标准的GCC扩展,它返回在其中评估的最后一项的值。 它与一般范围操作符非常相似,除了最后的固有返回。

这是一个宏,就像任何其他#DEFINE一样。 实质上,编译器将MAX(a,b)替换为其中定义的代码。 这将返回最大值。