Operator Precedence

Jul 29, 2012 at 8:34am
Hi everyone.
I've some questions about Operator Precedence.
1. What is value of this code.
int a = 3, result;
result = ++a + ++a;
when i test this code in "Dev C++" and "Visual C++ in Visual Studio", the result variable value is 10. Why 10 and not 9?

2. value of below code
int a = 3, result;
result = (a + 2) + ++a;
is 10. Why?
According to Operator Precedence in C++, priority of parentheses is higher than prefix increment, i mean it is expected that result be 9 but mentioned editors says 10.
Please help me.
Regards MRRITE

Jul 29, 2012 at 8:51am
Operator precedence doesn't say in what order the expressions should be evaluated.

result = ++a + ++a;
This is undefined behaviour.

result = (a + 2) + ++a
This is also undefined behaviour.
Jul 29, 2012 at 9:32am
Excuse me Peter87, i didn't get it. What you mean "undefined behaviour"?
Could you explain your answer more?
Thanks for your reply.
Last edited on Jul 29, 2012 at 9:33am
Jul 29, 2012 at 10:06am
I think it's undefined becouse of the possible optimizations that are done.
try this program for example:
1
2
3
4
void foo(int a, int b)
{
    cout<<a<<" "<<b<<endl;
}

Now call it with all possible compinations of a, a++ and ++a, and see the "undefinedness".
I think that both operations are done in the same time, and have impact for both inputs, but an internal order is kept, so when the first one is the postfix operator, it only incerments the other one, while the prefix operator increments both. I think it is pretty well defined, but HIGLY ununderstandable(overstandable?).
Jul 29, 2012 at 10:07am
As for (a+2)+ ++a, I don't see how that's undefined. It follows the same rules as above: the prefix operator increments both "a"s, so it become (4+2)+4.
Jul 29, 2012 at 10:21am
Undefined behaviour just means that anything could happen. The standard doesn't give any guarantees. You should avoid invoking undefined behaviour at all costs.

§1.9/15
Except where noted, evaluations of operands of individual operators and of subexpressions of individual expressions are unsequenced. [ Note: In an expression that is evaluated more than once during the execution of a program, unsequenced and indeterminately sequenced evaluations of its subexpressions need not be performed consistently in different evaluations. — end note ] The value computations of the operands of an operator are sequenced before the value computation of the result of the operator. If a side effect on a scalar object is unsequenced relative to either anotherside effect on the same scalar object or a value computation using the value of the same scalar object, the behavior is undefined.


The last sentence in above paragraph is the most import here.
(a + 2) + ++a
++a is an example of what they mean by "side effect on a scalar object". The first use of a is a "value computation using the value of the same scalar object".
Last edited on Jul 29, 2012 at 10:26am
Jul 29, 2012 at 10:29am
Prefix operators in a function call change every appearance of that variable, while postfix operators only change the ones that appear after them in the function call. I would say this is AT LEAST implementation-defined!
Jul 29, 2012 at 10:45am
N3376 §1.9.15: [...] the behavior is undefined.

viliml wrote:
I would say this is AT LEAST implementation-defined!

Well, maybe you should tell Stroustrup et al. about your findings... =)
Jul 29, 2012 at 10:47am
@viliml
I see no function calls.
If you call a function foo(a, a++); the behaviour is still undefined because
value computations and side effects associated with different argument expressions are unsequenced
so it suffers the same problem as above.
Jul 29, 2012 at 10:54am
I see no function calls.

Operators are functions with a shortened syntax. You can alway call them with the full "operator whatever(arguments)", or "objects.operator whatever(arguments)".
[quote]value computations and side effects associated with different argument expressions are unsequenced
[/quote]
I explained everything in my last post.
Last edited on Jul 29, 2012 at 10:58am
Jul 29, 2012 at 11:08am
Operators are functions with a shortened syntax.

Only user-defined operators are functions.

You can alway call them with the full "operator whatever(arguments)", or "objects.operator whatever(arguments)".

Does this compile for you? operator+(1, 5);

I explained everything in my last post.

Your explanation is wrong.
Jul 31, 2012 at 11:48am
Thanks for your answers. As result (from this discussion and other resources), C++ has defined Operator Precedence and not Operand Precedence. I mean operands (sub expression) can be evaluated in different order. For example in + operator left operand and right operand can be evaluated any order.

And for this expression result = ++i + ++i;, C++ standard says that result is undefined, because of modifying a variable more than one in an expression. In this case i didn't understand exactly reason of it.

Last edited on Jul 31, 2012 at 11:52am
Jul 31, 2012 at 12:34pm
result is undefined, because of modifying a variable more than one in an expression. In this case i didn't understand exactly reason of it.


The reason is that, unlike functions, the built-in operators can be merged by the compiler: the individual CPU instructions of multiple operators in the same expression (from one sequence point to the next) are interleaved in the way that makes the best use of pipelining, caching, and other low-level resources.

To do this correctly, C introduced, and C++ adopted these guarantees: you, the programmer, guarantee to the compiler that you're not going to make it possible to read a variable while another operator is modifying it, and you're not going to make it possible to modify the same value simultaneously with two operators.

The compilers don't ever expect this to happen, so the results of compiling expressions that violate these guarantees are unpredictable.
Last edited on Jul 31, 2012 at 1:06pm
Jul 31, 2012 at 1:11pm
Very good Cubbi. I now understand it, but could you explain your reply with an example, of course if it is possible? (for these sentences: "unlike functions, the built-in operators can be merged by the compiler", "from one sequence point to the next" and "interleaved")
Last edited on Jul 31, 2012 at 1:14pm
Topic archived. No new replies allowed.