Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unordered function evaluation for functions returning void

Is there a way in C and C++ to cause functions returning void to be evaluated in unspecified order?

I know that function arguments are evaluated in unspecified order so for functions not returning void this can be used to evaluate those functions in unspecified order:

#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());
}

Legal C and C++ code compiled by a conforming compiler may print hi, bye, and moo in any order. This is not undefined behavior (nasal demons would not be valid), there is simply more than one but less than infinite valid outputs and a compliant compiler need not even be deterministic in what it produces.

Is there any way to do this without the dummy return values?

Clarification: This is an abstract question about C and C++. A better original phrasing might have been is there any context in which function evaluation order is unspecified for functions returning void? I'm not trying to solve a specific problem.

like image 250
Praxeolitic Avatar asked Dec 03 '14 04:12

Praxeolitic


1 Answers

You can take advantage of the fact that the left hand side of a the comma operator is a discarded value expression (void expression in C) like this (see it live):

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

From the draft C++ standard section 5.18 Comma operator:

A pair of expressions separated by a comma is evaluated left-to-right; the left expression is a discarded-value expression (Clause 5).

and C11 section 6.5.17 Comma operator:

The left operand of a comma operator is evaluated as a void expression; there is a sequence point between its evaluation and that of the right operand. Then the right operand is evaluated; the result has its type and value.

As Matt points out is is also possible to mix the above method with arithmetic operators to achieve unspecified order of evaluation:

(hi(),0) + (bye(),0) + (moo(),0) ;
like image 200
Shafik Yaghmour Avatar answered Oct 18 '22 13:10

Shafik Yaghmour