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

时间:2014-12-03 04:37:28

标签: 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());
}

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

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

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

2 个答案:

答案 0 :(得分:9)

您可以利用以下事实:逗号运算符的左侧是废弃的值表达式( 中的 void表达式),如下所示( see it live < / em>的):

int main(void) {
    dummy((hi(),0), (bye(),0), (moo(),0));
}

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

  

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

和C11部分6.5.17 逗号运算符

  

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

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

(hi(),0) + (bye(),0) + (moo(),0) ;

答案 1 :(得分:-1)

总是有一种明显的方法是将指针放在容器中的函数中,将其重新排列(或者在评论中对其进行排序),并调用容器中的每个项目。如果您需要每次运行都具有相同的行为,请确保每次种子都相同。