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

ief*_*rge 6 c++ visual-studio visual-c++

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

#include <stdio.h>
struct S {
    int x;
};

int getNum() {
    printf("get num\n");
    return 4;
}

int main(int argc, char **argv) {
    struct S s = argc ? (struct S) { .x = getNum() } : (struct S) { .x = getNum() };
    printf("%d\n", s.x);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

印刷:

get num
get num
4
Run Code Online (Sandbox Code Playgroud)

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

Ayx*_*xan 8

根据 C++11 \xc2\xa75.16.1 条件运算符

\n\n
\n

条件表达式从右到左分组。第一个表达式根据上下文转换为 bool(第 4 条)。对其进行求值,如果为真,则条件表达式的结果是第二个表达式的值,否则是第三个表达式的值。仅计算第二个和第三个表达式中的一个\n。与第一个表达式关联的每个值计算和副作用都在与第二个或第三个表达式关联的每个值计算和副作用之前排序。

\n
\n\n

根据 C11 \xc2\xa76.5.15 条件运算符

\n\n
\n

第一个操作数被求值;它的求值与第二个或第三个操作数的求值(以求值者为准)之间有一个序列点。仅当第一个操作数与 0 比较时不等于 0 时,才会计算第二个操作数;仅当第一个操作数比较等于 0 时才计算第三个操作数;\n 结果是第二个或第三个操作数(以计算结果为准)的值,并转换为下面描述的类型。

\n
\n