2010-07-11 13 views
9

Bu kod snippet'i ANSI C'de iyi tanımlanmış mı? Sistemimde (Linux x86_64) sadece iyi çalışıyor ve bir adres yazıyor gibi görünüyor, ancak her zaman böyle olacak mı? Örneğin. Parametre bir kayıt aracılığıyla geçirilebilir ve bunun adresinin alınması doğru görünmez.Bir işlev parametresinin adresini almak yasal mı?

#include <stdio.h> 

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

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

DÜZENLEME: GCC, adresi almadan önce kayıt defterine geçirilen değeri yığına koyacaktır.

<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 

cevap

8

Evet, bu tamamen yasal - elbette çünkü foo döner, bu anlamsız zaman, işlevinden bu adresi dönmek olmazdı.

1

Bu tamamen yasal. Ama adresinizi aldığınızın kapsamını ve ömrünü düşünmelisiniz.

İşlevden geri göndermeye devam ederseniz, bu adres artık geçerli verilere işaret etmeyebilir. C'nin çoğunda olduğu gibi, bu size kendinizi ayağınıza vurma yeteneği verir.

16

Karışıklıklarınızı gidermek için: Evet, argüman tarafından bir kayıttan geçirilmiş olabilir, ancak çağrılan işlevde yerel bir değişken olduğunda, diğer yerel değişkenlerde olduğu gibi. Eğer adres alınır ve kullanılırsa, derleyici gerçek bir yığın değişkeni oluşturarak erişilebildiği gerçek bir adrese sahip olduğundan emin olmalıdır. Aksi takdirde, derleyici, bir kayıt defterinde hiçbir zaman anıta ulaşmadan onu tutmak için optimize edebilir.

+2

+1, cevabınız daha eksiksiz :) – Stephen

İlgili konular