Ansgar Lampe
Ansgar Lampe

Reputation: 650

Using newly declared variable in initialization (int x = x+1)?

I just stumbled upon a behavior which surprised me:

When writing:

int x = x+1;

in a C/C++-program (or even more complex expression involving the newly created variable x) my gcc/g++ compiles without errors. In the above case X is 1 afterwards. Note that there is no variable x in scope by a previous declaration.

So I'd like to know whether this is correct behaviour (and even might be useful in some situation) or just a parser pecularity with my gcc version or gcc in general.

BTW: The following does not work:

int x++;

Upvotes: 10

Views: 4301

Answers (8)

Ben Voigt
Ben Voigt

Reputation: 283624

Your code has two possiblities:

  1. If x is a local variable, you have undefined behavior, since you use the value of an object before its lifetime begins.
  2. If x has static or thread-local lifetime, it is pre-initialized to zero, and your static initialization will reliably set it to 1. This is well-defined.

You may also wish to read my answer that covers related cases, including variables of other types, and variables which are written to before their initialization is completed

Upvotes: 1

paxdiablo
paxdiablo

Reputation: 881323

With the expression:

int x = x + 1;

the variable x comes into existence at the = sign, which is why you can use it on the right hand side. By "comes into existence", I mean the variable exists but has yet to be assigned a value by the initialiser part.

However, unless you're initialising a variable with static storage duration (e.g., outside of a function), it's undefined behaviour since the x that comes into existence has an arbitrary value.

C++03 has this to say:

The point of declaration for a name is immediately after its complete declarator (clause 8) and before its initializer (if any) ...

Example:
int x = 12;
{ int x = x; }
Here the second x is initialized with its own (indeterminate) value.

That second case there is pretty much what you have in your question.

Upvotes: 18

Praveen
Praveen

Reputation: 331

3.3.1 Point of declaration 1 The point of declaration for a name is immediately after its complete declarator (clause 8) and before its initializer (if any), except as noted below. [ Example: int x = 12; { int x = x; } Here the second x is initialized with its own (indeterminate) value. —end example ]

The above states so and should have indeterminate value, You are lucky with 1.

Upvotes: 1

stefaanv
stefaanv

Reputation: 14392

The variable is defined from the "=" on, so it is valid and when it is globally defined, it is initialized as zero, so in that case it is defined behavior, in others the variable was unintialized as as such still is unitialized (but increased with 1).
Remark that it still is not very sane or useful code.

Upvotes: 3

npclaudiu
npclaudiu

Reputation: 2441

This is undefined behaviour and the compiler should at least to issue a warning. Try to compile using g++ -ansi .... The second example is just a syntax error.

Upvotes: 0

Shahbaz
Shahbaz

Reputation: 47503

int x = x + 1;

is basically

int x;
x = x + 1;

You have just been lucky to have 0 in x.

int x++;

however is not possible in C++ at a parser level! The previous could be parsed but was semantically wrong. The second one can't even be parsed.

Upvotes: 5

Some programmer dude
Some programmer dude

Reputation: 409166

In the first case you simply use the value already at the place in memory where the variable is. In your case this seems to be zero, but it can be anything. Using such a construct is a recipe for disaster and hard to find bugs in the future.

For the second case, it's simply a syntax error. You can not mix an expression with a variable declaration like that.

Upvotes: 3

Luchian Grigore
Luchian Grigore

Reputation: 258568

It's not, it's undefined behavior.

You're using an uninitialized variable - x. You get 1 out of pure luck, anything could happen.

FYI, in MSVS I get a warning:

Warning 1 warning C4700: uninitialized local variable 'i' used

Also, at run-time, I get an exception, so it's definitely not safe.

Upvotes: 8

Related Questions