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.
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) ;
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With