是否允许三元运算符在C++中计算两个操作数?



在将一些C代码移植到Windows时,我在MSVC++中发现了一个有趣的三元运算符行为。编译器似乎在以下示例中围绕? :计算这两个分支:

#include <stdio.h>
struct S {
int x;
};
int getNum() {
printf("get numn");
return 4;
}
int main(int argc, char **argv) {
struct S s = argc ? (struct S) { .x = getNum() } : (struct S) { .x = getNum() };
printf("%dn", s.x);
return 0;
}

指纹:

get num
get num
4

但是,GCC和Clang只评估getNum()一次。哪种行为是正确的或标准允许的?

根据 C++11 §5.16.1 条件运算符:

条件表达式从右到左分组。第一个表达式是 上下文转换为布尔值(第 4 条(。它被评估,如果它 为 true,则条件表达式的结果是 第二个表达式,否则是第三个表达式。只有一个 计算第二个和第三个表达式。每个值 与第一个表达式相关的计算和副作用是 在每个值计算和相关副作用之前排序 使用第二个或第三个表达式。

根据 C11 §6.5.15 条件运算符:

计算第一个操作数;在其 评估和第二或第三操作数的评估 (以评估者为准(。仅当以下情况下才计算第二个操作数 第一个比较不等于 0;仅计算第三个操作数 如果第一个比较等于 0;结果是 第二个或第三个操作数(以计算值者为准(,转换为 类型如下所述。

最新更新