For me the first thing to come in mind is the uncertain expression evaluation order, for example:
Edit: worse than ev. order.
1 2
i = 0;
j = i++ + ++i;
So that can give you either 2 or 1, I don't know if there are any cases, where it'd give 1, but supposedly there are, because evaluation order is said to be not specified by C++. (right?)
Edit: true about ev. order, but not about the j value.
What examples of that and other kinds would you offer? (this is actually a bit more just for fun, but anyway...)
That's not ambiguous, it's undefined behavior. The difference being that something ambiguous has more than one possible meaning (e.g. a function is overloaded for taking an integer and a pointer and the programmer passes a zero without any explicit casting), while undefined behavior has exactly one meaning. It's just that the meaning is unknowable without more information than the standard provides.
i++ + ++i could sensibly evaluate to 3, too, if it were to compile to
1 2 3 4
i++; //pre-increment is done before the expression
temp=i;
i++; //post-increment is done immediately after the value is taken
temp+=i;
Well, I'd say, you just see "undefined behavior" as more appropriate word, because, if I look in my english dict., I have "open to two or more interpretations" and similar, which seems at least just more uncertain concept for the case...
And about the value of 3: do you believe it, knowing, that
* it's the same i, so can't be incremented separately for both ++es => one is first, two cases exist;
* ++i returns its value of i before it gets incremented [1]!
Edit: what a mess, i++ returns value of i before incrementation!
Instructing? Well, for the first thing -- 'would', so not instructing, rather I was eager to see some comment from (perhaps) an English speaker on that wording.
And the second thing just didn't seem possible to me, so I put an '!' after my argumentation, which lets you write as you did, taken.
That link says:
Between the previous and next sequence point a scalar object shall have its stored value modified at most once by the evaluation of an expression.
So i can change its value no more than once per expression? If that's the same value taken for expression, would result in {0, 2, 4} possible answers. IF. I wonder, what can I take away from all this?
* it's the same i, so can't be incremented separately
Why not? Before you answer, keep in mind that the standard only guarantees that pre-increment is done at some time after the start of the expression and before the value of the variable is taken, and post-increment is done at some time after the value of the variable is taken and before the end of the expression.
If that's the same value taken for expression, would result in {0, 2, 4} possible answers.
Huh? Would you mind expanding?
EDIT: Oh, I forgot. Does anyone know if i++ || i++ and i++,i++ are also undefined? The former seems probable, but I'm not too sure of the latter.
@helios
the former does not include a sequence point, so it is undefined, while the latter is only defined if not in a function argument list, since ',' is a sequence point marker. :-\
@Skillless
inside a function argument list, the ',' is not a sequence point. I think this is odd, but the language specifies that it may evaluate function arguments in any order. Alas.
@KarlisRepsons
I am a native English speaker. Moreover, I've studied it very carefully -- more than most people. You were quibbling with helios about your choice of words when he corrected you.
The resulting value of i++ + ++i can be -7 or 5921624 with equal probability.
In response to your original posting, I don't think I have any "favorite" weird behaviors... :-D
Hi,
2 cents form my side, I think it is well defined, it will work like this---
first preference will for for increment operator so, and work from right to left.
j= i++ + ++i;
now from right side i= 1 now it will pass this value to left side and the i++ will take that value and put that value in temp and yield original value after that will do increment. SO it will be
1 2
j= temp+1;
j=1+1 =2;
post prefix always store original value to temp and yield that temp.
if the code will be
1 2 3
int i = 0;
int j = ++i + ++i;
cout<< j;
Then j= 4
again from right side ++i, i will be one and it will pass the value to left side and the left i will also increase i by one and, i will be 2 and it will become 2+2 =4.
Actually, I just noticed I didn't mention that here.
Well, basically, the value of an expression is undefined if a value that's being incremented or decremented appears more than once in it.
For example, (x++ + x), (x-- + x), (++x + x), (--x + x--).
now again take from right side, x=0 this value will pass to lefts side ans left
side is x++, so it will keep the original value in temp and yield that value after that
will do increment so the x is still 0.
z=0+0=0; ANS
second case
1 2
int x=0;
int z= x-- + x;
from right side x=0 and this value will goto left side again the same thing x-- will yield the original value before decrement so the x is still 0
z=0+0=0 ANS
Third case
1 2 3 4
int x=0;
int z= ++x + x;
Take from right side x=0 the value passed to left side and ++x did the increment and yield that new value which is 1 so now x is 1.
Z=1+1=2 ANS
fourth case
1 2 3 4
int x=0;
int z=--x + x--;
from right x=0 the x-- will put the original value int temp and will pass that value to left side and left side --x will do the increment by one so now the x is -1
"For me"? I'm sorry, I thought we were discussing programming, not modern expressionism. Maybe I was wrong.
Your reasoning is wrong. You're assuming compilers have to implement order of evaluation in any particular order. In fact, they don't. That's why the behavior is said to be undefined.
x++ + x could compile to
1 2 3
temp=x;
x++;
temp+=x;
in one compiler, and to
1 2 3
temp=x;
temp+=x;
x++;
in another.
Hell, the same compiler could generate different code in different contexts if it finds that it's faster:
1 2 3 4 5
int a=0,b,c;
b=a++ + a;
a=0;
c=a++ + a;
std::cout <<(b==c); //it's impossible to know what this will output without trying it
But one thing is simple Postfix Operators Return the Unincremented Value and this is well defined in c++ as per Stanley B. Lippman and Bjarne Stroustrup.
So how can these thing be undefined, if x++ is defined and ++x is also defined then how can x++ + ++x be undefined while increment operator has a precedence over unary plus.
Both functions, f1 and f2, would be called prior to operator+, right? The order in which those subexpressions are evaluated is not explicitly defined. So, if either f1 or f2 depended on the other, the results could vary among different compiler implementations.
The subexpressions, x++ and ++x, are dependent on each other. The result of the entire expression is undefined because it is different according to which subexpression is evaluated first (and that is undefined).