-1

Below code is getting compiled in MinGw. How does it get compiled? How is it possible to assign a variable which is not yet created?

 int main()
{
    int*p=p;
    return 0;
}
  • 4
    Related to [Does initialization entail lvalue-to-rvalue conversion? Is `int x = x;` UB?](http://stackoverflow.com/q/14935722/1708801) and [Has C++ standard changed with respect to the use of indeterminate values and undefined behavior in C++14?](http://stackoverflow.com/q/23415661/1708801) – Shafik Yaghmour Apr 06 '15 at 12:05
  • Mainly that the scope of `p` includes its initializer. – chris Apr 06 '15 at 12:07
  • it is created, it's just uninitialized. so, that's undefined behavior. it may compile. it may not compile. it may set your house on fire. – The Paramagnetic Croissant Apr 06 '15 at 12:12

3 Answers3

5

How does it get compiled?

The point of declaration of a variable starts at the end of its declarator, but before its initialiser. This allows more legitimate self-referential declarations like

void * p = &p;

as well as undefined initialisations like yours.

How is it possible to assign a variable which is not yet created?

There is no assignment here, just initialisation.

The variable has been created (in the sense of having storage allocated for it), but not initialised. You initialise it from whatever indeterminate value happened to be in that storage, with undefined behaviour.

Most compilers will give a warning or error about using uninitialised values, if you ask them to.

Mike Seymour
  • 249,747
  • 28
  • 448
  • 644
1

Let's take a look at what happens with the int*p=p; statement:

  1. The compiler allocates space on the stack to hold the yet uninitialized value of variable p
  2. Then the compiler initializes p with its uninitialized value

So, essentially there should be no problem with the code except that it assigns a variable an uninitialized value.

Actually there is no much difference than the following code:

int *q;        // define a pointer and do not initialize it
int *p = q;    // assign the value of the uninitizlized pointer to another pointer
Amnon Shochot
  • 8,998
  • 4
  • 24
  • 30
0

The likely result ("what it compiles to") will be the declaration of a pointer variable that is not initialized at all (which is subsequently optimized out since it is not used, so the net result would be "empty main").

The pointer is declared and initialized. So far, this is an ordinary and legal thing. However, it is initialized to itself, and its value is only in a valid, initialized state after the end of the statement (that is, at the location of the semicolon).
This, unsurprisingly, makes the statement undefined behavior.

By definition, invoking undefined behavior could in principle cause just about everything (although often quoted dramatic effects like formatting your harddrive or setting the computer on fire are exaggerated).

The compiler might actually generate an instruction that moves a register (or memory location) to itself, which would be a no-op instruction on most architectures, but could cause a hardware exception killing your process on some exotic architectures which have special validating registers for pointers (in case the "random" value is incidentially an invalid address).
The compiler will however not insert any "format harddisk" statements.

In practice, optimizing compilers will nowadays often assume "didn't happen" when they encounter undefined behavior, so it is most likely that the compiler will simply honor the declaration, and do nothing else.
This is, in every sense, perfectly allowable in the light of undefined behavior. Further, it is the easiest and least troublesome option for the compiler.

Damon
  • 67,688
  • 20
  • 135
  • 185