Home > Mobile >  Why does x have an unexpected value after trying to initialize it with x, y = a, b?
Why does x have an unexpected value after trying to initialize it with x, y = a, b?

Time:10-06

#include <iostream>

int main() {
    int x, y;
    x, y = 10, 20;
    std::cout << x;
    return 0;
}

I want 10 as output but 16 is coming.

CodePudding user response:

x, y = 10, 20; is interpreted as (x), (y = 10), (20);.

The three expressions are just executed sequentally. x and 20 do nothing, and y = 10 does what it says on the tin.

x remains uninitialzied, and reading it is undefined behavior.


There is a way to do what you want, but it's a part of the standard library (#include <tuple>), not built into the language.

It's also quite verbose, so it might be a better idea to just assign to each variable separately.

If you want to assign to existing variables:

int x, y;
std::tie(x, y) = std::forward_as_tuple(10, 20);

Or, if you want to create new variables:

auto [x, y] = std::forward_as_tuple(10, 20);

(the auto [...] syntax is called a structured binding, and is available since C 17)


If the rhs are variables (lvalues), you can use less verbose std::tie instead of std::forward_as_tuple.

In some cases you need std::tuple instead of std::forward_as_tuple, it will copy/move the rhs before assigning them. This is required e.g. when returning the tuple from a function, or if you want to do std::tie(x, y) = std::tuple(y, x);.

You can also use std::tuple instead of std::forward_as_tuple for brevity, is the rhs is inexpensive to copy/move.

CodePudding user response:

It seems that you want to do in C what is ok in languages like Python. This line

x, y = 10, 20

in Python will do what you want: it will initialize x to 10 and y to 20. But in C it does something very different. The comma operator in C works as follows: given E1, E2, E3; expression C will evaluate E1 and discard its result, evaluate E2 and discard its result, evalute E3 and return it as a value of the entire expression (in your case it will be discarded as well, since there is no left side).

And so in C the

x, y = 10, 20

expression does what follows: reads x, sets y = 10 and reads 20. Therefore your

std::cout << x;

line has Undefined Behaviour, you print an uninitialized variable (well, you already have UB in the expression itself as well). This means that anything can happen: x can be anything, including 16 in your case, but also your program may simply crash.

Note that C does have tools to emulate this "Python like behaviour" (see HolyBlackCat's answer) but I suggest simply doing

int x = 10;
int y = 20;

Not a one-liner, but easy to read and understand.

  •  Tags:  
  • c
  • Related