Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the reason for this output? [duplicate]

Tags:

c++

I have the following code.

    int x=80;
    int &y=x;
    x++;
    cout<<x<<" "<<--y;

The output comes out to be 80 80. And I don't understand how. I thought the output of x would be 81 although I don't know anything about y. How is the reference variable affected by the decrement operator. Can someone please explain?

like image 897
Emperor Penguin Avatar asked Aug 25 '13 07:08

Emperor Penguin


People also ask

What causes duplicate data?

Data aggregation and human typing errors are some of the sources of duplicate data. Customers may also provide a company with different information at different points in time. Hence, businesses should consider removing duplicate records from their Database.

What causes duplicates in SQL?

Are you joining tables with one to many relationships? This will often result in the same rows being returned multiple times. If there are multiple child rows connected to a parent. The other more obvious reason could be that you actually have duplicate data in your database.

Why does Access query return duplicates?

Duplicate data often creeps in when multiple users add data to the Access database at the same time or if the database wasn't designed to check for duplicates. Duplicate data can be either multiple tables containing the same data or two records containing just some fields (columns) with similar data.


2 Answers

The expression is evaluated as:

((cout << x) << " ") << --y;

There is no sequence point (or ordering) between the evaluation of the left-hand side and the right-hand side of the expression, the compiler can output code that evaluates --y as the first step.

Since y is a reference to x here, this is actually undefined behavior since you're both reading from and writing to x in the same expression without intervening sequence points.

like image 124
Mat Avatar answered Sep 20 '22 15:09

Mat


One nasty thing about redirection operators << is that they intuitively convey an indea of "sequential computation" that indeed is not present.

When you write

std::cout << f() << g() << std::endl;

the output will show first the result of f() and then the result of g(), but the actual call to g() may happen before the call to f().

It even gets worse than this... it's not that the sequence is not predictable, but that indeed the very concept of sequence is not valid. In

std::cout << f(g()) << h(i()) << std::endl;

it's for example legal that the first function being called is g(), followed by i(), followed by h() and finally by f(). It's not even guaranteed that order will be the same for all invocations (not because compiler makers likes to make fun of you, but because the code can be inlined and the compiler may decide a different order if the containing function is inlined in a different context).

The only C++ operators that guarantee a sequence in the evaluation order are:

  1. &&: first evaluates left side and only if the result is "true" evaluates the right side
  2. ||: first evaluates left side and only if the result is "false" evaluates the right side
  3. ?:: evaluates first the condition and then only the second or the third operand
  4. ,: the comma operator... evaluates the left side, drops the value and then evaluates and returns the right side. NOTE: the commas between function parameters are NOT comma operators and no evaluation order is imposed.

Moreover this guaratee is valid only for the predefined operators. If you overload &&, || or , in your class they're just normal operators without any special restrictions on evaluation order.

Any other operator doesn't impose any restriction on the evaluation order, and this includes << even if the usage sort of tricks you into thinking that.

like image 24
6502 Avatar answered Sep 21 '22 15:09

6502