函数返回void的无序函数评估

Pra*_*tic 8 c c++ language-lawyer

在C和C++中是否有一种方法可以使返回void的函数以未指定的顺序进行求值?

我知道函数参数是以未指定的顺序计算的,因此对于不返回void的函数,可以使用它来以未指定的顺序评估这些函数:

#include <stdio.h>

int hi(void) {
    puts("hi");
    return 0;
}

int bye(void) {
    puts("bye");
    return 0;
}

int moo(void) {
    puts("moo");
    return 0;
}

void dummy(int a, int b, int c) {}

int main(void) {
    dummy(hi(), bye(), moo());
}
Run Code Online (Sandbox Code Playgroud)

由符合编译器编译合法的C和C++代码可以打印hi,byemoo以任何顺序.这不是未定义的行为(鼻子恶魔不会有效),只有不止一个但不是无限的有效输出,并且兼容的编译器甚至不需要确定它产生什么.

没有虚拟返回值,有没有办法做到这一点?

澄清: 这是一个关于C和C++的抽象问题.一个更好的原始措辞可能是有任何上下文,其中函数评估顺序未指定返回void的函数?我不是想解决一个具体的问题.

Sha*_*our 10

您可以利用以下事实:逗号运算符的左侧是丢弃的值表达式(C中的void表达式),如下所示(请参见实时):

int main(void) {
    dummy((hi(),0), (bye(),0), (moo(),0));
}
Run Code Online (Sandbox Code Playgroud)

从草案C++标准部分5.18 逗号运算符:

用逗号分隔的一对表达式从左到右进行评估; 左表达式是丢弃值表达式(第5条).

和C11部分6.5.17 逗号运算符:

逗号运算符的左操作数被计算为void表达式; 它的评估与右操作数之间存在一个序列点.然后评估右操作数; 结果有它的类型和价值.

正如Matt指出的那样,也可以将上述方法与算术运算符混合,以实现未指定的评估顺序:

(hi(),0) + (bye(),0) + (moo(),0) ;
Run Code Online (Sandbox Code Playgroud)

  • 你根本不需要`dummy`,因为其他运营商的评估顺序也没有说明; 例如`(hi(),0)+(bye(),0)+(moo(),0);` (2认同)