这是一个有效的函数吗?

Is this a valid function?

本文关键字:有效 函数 一个      更新时间:2023-10-16

函数参数中的引用发生了什么,如果它在函数返回时被销毁,那么const int *i如何仍然是一个有效的指针?

const int* func(const int &x = 5)
{
    return &x;
}

int main()
{
    const int *i = func();
}

§12.2/5:

"函数调用(5.2.2)中与引用形参的临时绑定一直存在,直到包含该调用的完整表达式完成为止。"

这意味着当i被初始化时,它正在获取一个临时对象的地址,该对象在该点确实存在。然而,一旦i初始化,临时对象将被销毁,i将成为另一个悬空指针。

就其本身而言,该函数是有效的——但是对于您编写的周围代码,之后添加的任何试图解引用i的代码都会给出未定义的行为。

指针有值并不意味着它就是一个有效的指针。

在这种情况下,它保存了一个曾经是x的地址,很可能这个地址的值仍然是5,但它不是一个有效的指针,你不能指望这个值在那里

int i指向一个不安全的内存补丁,它不是一个有效的指针。

变量"i"仍然是一个指针,但即使读取它指向的值也会给您带来未定义的行为。这就是为什么你永远不应该编写像func.

这样的函数。

我认为x是在设置对func()的调用时作为堆栈上的未命名临时创建的。这个临时对象将至少存在到调用方中的语句结束。所以int* i是完全有效的。它只在语句结束时失效——这意味着你不能使用它。

在标准中有一些关于未命名的临时变量被保留,直到对它们的最后一个引用超出范围,但我认为它没有涵盖这个显式和隐藏的间接。

5为程序数据。它在数据段中,而不是堆栈或堆中。

因此,指针或对它的引用在程序运行期间仍然有效。

每次调用函数时都会计算默认参数,因此调用func()实际上是将临时变量绑定到const引用的func(5)。然后将该临时对象的生命周期延长到函数结束并销毁该对象。在此之后指向该对象的任何指针都是无效的,解引用是未定义的行为。