2010-07-11 14 views
9

¿Este fragmento de código está bien definido en ANSI C? En mi sistema (Linux x86_64) parece funcionar bien e imprimir una dirección, pero ¿siempre será el caso? P.ej. el parámetro se puede pasar a través de un registro, y tomar la dirección de eso no parece correcto.¿Es legal tomar la dirección de un parámetro de función?

#include <stdio.h> 

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

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

EDIT: Parece que GCC pondrá el valor que se pasa por el registro en la pila antes de tomar la dirección de la misma.

<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 <[email protected]> 
    c9      leave 
    c3      ret 

Respuesta

8

Sí, esto es perfectamente legal - por supuesto que no regresaría esa dirección desde la función, porque en el momento foo devoluciones, no tiene sentido.

1

Es perfectamente legal. Pero debes pensar en el alcance y el tiempo de vida de lo que has obtenido la dirección.

Si logra pasarlo de la función, esa dirección puede que ya no esté apuntando a datos válidos. Como en gran parte de C, esto le da la capacidad de dispararse en el pie.

16

Para hacer frente a su confusión: Sí, el argumento podría ser pasó por un registro, pero cuando se convierte en una variable local en la función llamada, que es igual que cualquier otra variable local. Si se toma y utiliza su dirección, el compilador tendrá que asegurarse de que tiene una dirección real a través de la cual se puede acceder creando una variable de pila real. De lo contrario, el compilador puede optimizar para mantenerlo en un registro sin tener que crear una instancia en la memoria.

+2

+1, tu respuesta es más completa :) – Stephen

Cuestiones relacionadas