Действительно ли законно взять адрес параметра функции?

Действительно ли этот фрагмент кода четко определен в 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   
11
задан Maister 11 July 2010 в 13:47
поделиться

3 ответа

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

9
ответ дан 3 December 2019 в 03:17
поделиться

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

18
ответ дан 3 December 2019 в 03:17
поделиться

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

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

1
ответ дан 3 December 2019 в 03:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: