27

Is the following code undefined behavior, implementation defined or defined by the standard? I couldn't find any reference regarding assigning an integer to its own address.

volatile int x = (int)&x;

This code gets translated to:

lea         eax,[ebp-4]  
mov         dword ptr [ebp-4],eax 
Adrian McCarthy
  • 45,555
  • 16
  • 123
  • 175
Yuval
  • 907
  • 9
  • 24
  • 2
    I think this boils down to how casting addresses to integers is handled. The fact that it's stored in the integer itself, I think, is of no consequence. – templatetypedef Nov 11 '13 at 19:44
  • 1
    The value of `x` will be implementation defined, as long as `int` is at least as wide as `int *`; just like every other time you use `reinterpret_cast` to go from a pointer to an `int`. – avakar Nov 11 '13 at 19:44
  • 4
    I would say it is implementation defined. On some platforms, an `int` may not be able to hold the value of the pointer (address). For example, a 16-bit word system with 24-bit addressing. – Thomas Matthews Nov 11 '13 at 19:44
  • 11
    The famous C/C++ standard? – Pascal Cuoq Nov 11 '13 at 19:44
  • Also highly depends on the platform. There may not be accessible memory at all locations. – Thomas Matthews Nov 11 '13 at 19:45
  • Duplication of http://stackoverflow.com/questions/153065/converting-a-pointer-into-an-integer –  Nov 11 '13 at 19:45
  • Related: http://stackoverflow.com/questions/3567905/c-is-it-safe-to-cast-pointer-to-int-and-later-back-to-pointer-again – Shafik Yaghmour Nov 11 '13 at 19:47
  • Just about the wording in the title vs sample code shown, shouldn't this be: _'Assigning an int's own address to it's value'_? – πάντα ῥεῖ Nov 11 '13 at 19:49
  • 2
    @DieterLücking This is not a duplicate. I'm asking about the behavior of the compiler when assigning to a local integers it's own address whilst the question your'e pointing at deals with providing address as an argument to a function – Yuval Nov 11 '13 at 19:53
  • It's interesting to note that obviously the compiler didn't anticipate this and use eax as both the destination address and the value. Or is that because it's tagged volatile? – kfsone Nov 11 '13 at 20:21
  • @g-makulik: Your title is much better than mine :) – Yuval Nov 11 '13 at 21:35
  • @kfsone: the volatile keyword just keeps the compiler from optimizing the code away. – Yuval Nov 11 '13 at 21:40

3 Answers3

21

In C, using x in both the declaration and the initialization is fine:

(C99, 6.2.1p7) "[...] Any other identifier has scope that begins just after the completion of its declarator."

The result of the conversion of the pointer to the integer is implementation-defined and can be undefined behavior:

(C99, 6.3.2.3p7) "Any pointer type may be converted to an integer type. Except as previously specified, the result is implementation-defined. If the result cannot be represented in the integer type, the behavior is undefined. The result need not be in the range of values of any integer type."

ouah
  • 142,963
  • 15
  • 272
  • 331
11

In C++, according to the point of declaration rule. It's well defined. Because before =, the variable x is declared and then &x is known. Here is a tricky point, below code is undefined behavior:

int x = x;        // undefined behavior, using uninitialized variable

but...

int x = (int)&x;  // defined behavior

I'm talking about C++, but I believe it's valid for C too.

Community
  • 1
  • 1
masoud
  • 55,379
  • 16
  • 141
  • 208
2

In the ASM-code you show, the value of the pointer is first put into eax, and then the pointer is read from eax and put into the same location as the value of the integer was.

The only problem here is that an int not always is the same size as an int*. On my 64-bit machine, ints are 4 bytes and pointers are 8 bytes. If I had run your code on my box, i would get only half the pointer.

Atle
  • 1,867
  • 12
  • 10