tags:

views:

155

answers:

3

Is this code snippet well defined in ANSI C? On my system (Linux x86_64) it seems to run just fine and print an address, but will it always be the case? E.g. the parameter might be passed via a register, and taking the address of that doesn't seem right.

#include <stdio.h>

void foo(int a)
{
   printf("%p\n", &a);
}

int main(void)
{
   foo(42);
   return 0;
}

EDIT: Looks like GCC will put the value that is passed by register into the stack before taking the address of it.

<foo>:
  55                      push   rbp
  48 89 e5                mov    rbp,rsp
  48 83 ec 10             sub    rsp,0x10
  89 7d fc                mov    DWORD PTR [rbp-0x4],edi
  b8 1c 06 40 00          mov    eax,0x40061c
  48 8d 55 fc             lea    rdx,[rbp-0x4]
  48 89 d6                mov    rsi,rdx
  48 89 c7                mov    rdi,rax
  b8 00 00 00 00          mov    eax,0x0
  e8 d8 fe ff ff          call   4003c0 <printf@plt>
  c9                      leave  
  c3                      ret   
+8  A: 

Yes, this is perfectly legal - of course you wouldn't return that address from the function, because by the time foo returns, it's meaningless.

Stephen
+1  A: 

It's perfectly legal. But you need to think about the scope and lifetime of what you've gotten the address of.

If you contrive to pass it back out of the function, that address may not be pointing to valid data any more. As in much of C, this gives you the ability to shoot yourself in the foot.

Carl Smotricz
+6  A: 

To address your confusion: Yes, the argument might be passed by a register, but when it becomes a local variable in the called function, it's just like any other local variable. If it's address is taken and used, the compiler will have to ensure it has a real address through which it can be accessed by creating a real stack variable. If not, the compiler may be able to optimize to keep it in a register without ever instantiating it in memory.

R..
+1, your answer is more complete :)
Stephen