假设我有一个声明和初始化两个局部变量的函数——默认情况下它们具有 storage duration auto
。然后该函数调用第二个函数,将这两个局部变量的地址传递给该函数。第二个函数可以安全地使用这些指针吗?
一个简单的程序示例,以补充该描述:
#include <stdio.h>
int adder(int *a, int *b)
{
return *a + *b;
}
int main()
{
auto int a = 5; // `auto' is redundant; included for clarity
auto int b = 3;
// adder() gets the addresses of two auto variables! is this an issue?
int result = adder(&a, &b);
printf("5 + 3 = %d\n", result);
return 0;
}
该程序按预期工作,打印5 + 3 = 8
.
通常,当我对 C 有疑问时,我会求助于标准,这也不例外。具体来说,我检查了ISO/IEC 9899,§6.2.4。它在那里说,部分:
4 其标识符被声明为没有链接且没有存储类说明符的对象
static
具有自动存储持续时间。5 对于这种不具有可变长度数组类型的对象,其生命周期从进入与其关联的块开始,直到该块的执行以任何方式结束。(进入封闭的块或调用函数会暂停,但不会结束当前块的执行。)如果递归地进入块,则每次都会创建对象的新实例。对象的初始值是不确定的。如果为对象指定了初始化,则在执行块时每次到达声明时都会执行该初始化;否则,每次达到声明时,该值变得不确定。
读到这里,我推理以下几点:
变量
a
并且b
有 storage duration ,我已经使用关键字auto
明确说明了这一点。auto
调用
adder()
函数对应于第 5 节中的括号,在上面的部分引用中。也就是说,输入adder()
函数“暂停,但不结束”当前块(即main()
)的执行。由于该
main()
块不是“以任何方式结束[ed]”,因此可以保证存储a
和。b
因此,使用地址访问它们&a
,&b
甚至在内部adder()
,应该是安全的。
那么,我的问题是:我在这方面是否正确?还是我只是变得“幸运”并访问了偶然未被覆盖的内存位置?
PS我无法通过谷歌或SO的搜索找到这个问题的确切答案。如果可以,请将其标记为重复,我将其删除。