Законно ли брать адрес параметра функции? - PullRequest
11 голосов
/ 11 июля 2010

Хорошо ли этот фрагмент кода определен в ANSI C?В моей системе (Linux x86_64) кажется, что он работает нормально и печатает адрес, но так ли это будет всегда?Например, параметр может быть передан через регистр, и получение адреса, который кажется неправильным.

#include <stdio.h>

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

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

РЕДАКТИРОВАТЬ: похоже, что GCC поместит значение, переданное регистром в стек, прежде чем приниматьадрес этого.

<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   

Ответы [ 3 ]

18 голосов
/ 11 июля 2010

Чтобы устранить вашу путаницу: Да, аргумент может быть , передаваемый регистром , но когда он становится локальной переменной в вызываемой функции, он аналогичен любой другой локальной переменной. Если его адрес взят и используется, компилятор должен убедиться, что у него есть реальный адрес, через который он может быть получен путем создания реальной переменной стека. Если нет, компилятор может оптимизировать его для сохранения в регистре, даже не создавая его в памяти.

9 голосов
/ 11 июля 2010

Да, это совершенно законно - конечно, вы не вернете этот адрес из функции, потому что к моменту возврата foo это бессмысленно.

1 голос
/ 11 июля 2010

Это совершенно законно. Но вам нужно подумать о масштабах и сроке службы того, что вы получили по адресу.

Если вы решите передать его обратно из функции, этот адрес может больше не указывать на действительные данные. Как и в большей части Си, это дает вам возможность выстрелить себе в ногу.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...