Your favourite C++ undefined behaviours?

Pages: 12
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...)
Last edited on
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!

[1] http://www.cplusplus.com/doc/tutorial/operators
Last edited on
You are instructing someone who knows more about this stuff than you do.

"Undefined behavior" has exactly one interpretation: you cannot rely upon its behavior.

This whole thing is a constant topic among newbies:
http://www.parashift.com/c++-faq-lite/misc-technical-issues.html#faq-39.15

There is a reason that the language designers said "don't do that."

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?

I change thread subject also.
* 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.
Last edited on
doesnothing(int, int)
and then do..
doesnothing(puts("Hello "), puts("world!"));
the output is
world!
Hello

this helped me in making a scripting language =P reading lines from right to left is 100x easier compiling
Last edited on
@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
Duoas, I'd like to see your suggestions as of what should a person read to properly understand C++ undefined behaviour?
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.

Regards
check this one also use double and int.

1
2
int z,x=5,y=-10,a=4,b=2; 
z = x++ - --y * b / a;
rajroshi: I could argue with you, but I'd just be repeating what I've already said in this thread. No, you're wrong. Period.

However, the value of z here is defined:
1
2
int z,x=5,y=-10,a=4,b=2; 
z = x++ - --y * b / a;
@helios

May be I am. I would be thankful if you will correct me because I am in learning process so any help will be appreciated.

I don't want to develop misconceptions.

Thanx
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--).
@Helios


For me it is well defined.

Ok will will take all the case one by one.

First case

1
2
3
int x=0;
int z= 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

z= -1 + -1 = -2 ANS

Regards


For me it is well defined.
"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 
Last edited on
@Helios,
May be you are right.


std::cout <<(b==c); should be 1 at least in GNU GCC and visual c++ 2008 compiler for the rest may be you are right.

May be I developed this reasoning because of the behavior of my GNU GCC and visual c++ compiler.

Thanx for your advice I will try to check i with more compiler.



Try it with as many as you want. It won't prove anything.
@Helios

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.

Please clear my doubt.

Regards
Last edited on
If you had:
 
int x = f1() + f2();


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).
Last edited on
Pages: 12