Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is the following an undefined behavior? i = func(i)

I know that i=i++; is an undefined behavior, because i is changed twice before the sequence point ;.

But I don't know if the compiler guarantees the case as below is not an undefined behavior:

int func(int &i)
{
    i++;
    return i;
}

int i = 1;
i = func(i);
like image 681
Yves Avatar asked Feb 03 '17 09:02

Yves


People also ask

What is undefined behavior in C++?

So, in C/C++ programming, undefined behavior means when the program fails to compile, or it may execute incorrectly, either crashes or generates incorrect results, or when it may fortuitously do exactly what the programmer intended.

Does C# have undefined behavior?

The truly horrible kinds of Undefined Behavior which are encouraged in hypermodern C philosophy do not exist in C# or other .

Why does C++ allow undefined behavior?

Undefined behavior exists mainly to give the compiler freedom to optimize. One thing it allows the compiler to do, for example, is to operate under the assumption that certain things can't happen (without having to first prove that they can't happen, which would often be very difficult or impossible).


1 Answers

Firstly, modern C++ has switched from the old (inadequate) concept of "sequence points" to the new concept of "sequencing" (i.e. "sequenced before", "sequenced after"). While i = i++ is still undefined, i = ++i is actually perfectly defined now. Sequencing rules in many lvalue-returning operators were reworked.

Secondly, your version is safe under the old specification as well as under the new one. The modification of i inside the function is safely "isolated" from the assignment to i outside. In the classic specification sequence points at the beginning and at the end of the function safely separated the modifications (and reads) of i from each other. The new sequencing rules preserve the same level of protection as well.

An example that illustrates the protection provided by a function call might look as follows

int inc(int &i) { return i++; }
...
int i = 1;

int r1 = i++ * i++ * i++;          
// Undefined behavior because of multiple unsequenced side effects
// applied to the same variable

int r2 = inc(i) * inc(i) + inc(i);
// No UB, but order of evaluation is unspecified. Since the result 
// depends on the order of evaluation, it is unspecified

int r3 = inc(i) + inc(i) + inc(i); 
// Perfectly defined result. Order of evaluation is still unspecified, 
// but the result does not depend on it
like image 114
AnT Avatar answered Oct 11 '22 10:10

AnT