I'm in process of writing c expression parser and found behavior I don't understand:
#include <iostream>
#include <sstream>
int main()
{
std::string string1;
std::string string2 = std::string((string1 = std::string("first")) + " " + (string1 = std::string("second")));
std::cout << string1 << std::endl;
std::cout << string2 << std::endl;
int int1;
int int2 = (int1 = 1) + (int1 = 2);
std::cout << int1 << std::endl;
std::cout << int2 << std::endl;
std::cin.get();
return 0;
}
Output:
first
first first
2
4
I have expected:
second
first second
2
3
When running the same program in C#, I get the expected output. Could you please explain what's actually happening there?
C# code: https://gist.github.com/Kukkimonsuta/59543cfc4f7f73b8bebd
This code has undefined behavior in C++, because a single expression produces multiple side effects on the same variable (namely, two assignments to string1). Same goes for the int1 variable.
In your case, the compiler is applying these two side effects in the order that is reverse of what you have expected. Even if it did apply them in the order that you expected, this program would still remain invalid.
When running the same program in C#, I get the expected output.
Unlike C++, C# does not leave nearly as many decisions up to compiler developers. The order of evaluation of these expressions, as well as many other expressions that produce undefined behavior in C++, is well defined by the language standard.
This is undefined behavior in C and C++. Variable int1 is modified more than once in the same statement.
See Sequence point:
An often-cited example is the C expression
i=i++, which apparently both assignsiits previous value and incrementsi.... In C and C++, evaluating such an expression yields undefined behavior.`
and the footnote:
Clause 6.5#2 of the C99 specification: "Between the previous and next sequence point an object shall have its stored value modified at most once by the evaluation of an expression. Furthermore, the prior value shall be accessed only to determine the value to be stored."
Besides that, assuming we'd have different variables, the result would still not be guaranteed. C++ does not specify the order in which parts of expressions are evaluated, contrary to C#.
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