You are probably in the realm of "undefined behaviour", or possibly "depends which version of the standard" behaviour. I should avoid making changes to a variable in the midst of a complex output statement.
My compiler gives
0 0
to your original code, but cpp.sh gives
0 5
Neither give any warnings.
If your reset function changes v via a reference argument it might be better as a void function, although obviously you couldn't then put it in an output statement.
For safety's sake ...
1 2 3 4 5 6 7 8 9 10 11 12
#include <iostream>
int reset(int& v)
{
v = 0;
return 0; // <==== did you mean return v;
}
int main()
{
int i = 5;
std::cout << reset(i);
std::cout << " " << i; // <==== Use a separate statement
}
But consider the OP's original code (reproduced below) and run on the SAME online system - Rextester - with two of that system's compilers:
gcc ( https://rextester.com/l/cpp_online_compiler_gcc ) produces
0 5
Yes, separating the evaluation of reset(i) and the output of i into two separate statements is what I did in my first reply to the OP (albeit with two output statements, rather than an intermediate variable).
So we now have a fine distinction between:
- undefined
- unspecified
Ah, the semantics of the C++ language! Perhaps it is unspecified what the compiler will do with undefined behaviour. .... Or is that the other way round?
The way I understand it in practical terms, unspecified means that if you select from a finite list of possible outcomes, it will be one of those outcomes (hopefully, compiler documentation can tell you what that outcome is).
But undefined means anything could happen, especially when optimizations are turned on. So when the standard changed this behavior from undefined to unspecified, it prevents the optimizer from completely blowing apart your program, but it still might not do what you want.
Best to just avoid any of this "behavior".
implementation defined-behaviour:
behavior, for a well-formed program construct and correct data, that depends on the implementation and that each implementation documents. https://eel.is/c++draft/intro.defs#defns.impl.defined
unspecified behaviour:
behavior, for a well-formed program construct and correct data, that depends on the implementation.
[Note: The implementation is not required to document which behavior occurs.] https://eel.is/c++draft/intro.defs#defns.unspecified
In current C++ (C++17), the behaviour of the program is well-defined;
one would get the output that Ricoxor expects.
19) In a shift operator expression E1<<E2 and E1>>E2, every value computation and side-effect of E1 is sequenced before every value computation and side effect of E2 (since C++17) https://en.cppreference.com/w/cpp/language/eval_order