临时保管人的存储期限有什么要求?

What's the requirement for storage duration of temporaries?

本文关键字:什么 保管人 存储      更新时间:2023-10-16

考虑以下代码:

class Test() {
public:
    Test()
    {
       memset( buffer, 0, sizeof( buffer ) );
    }
    void Process()
    {
       printf( buffer );
    }
private:
    char buffer[1000];
};
int main()
{
    Test().Process();
    char buffer[1000] = {};
    print( buffer );
    return 0;      
}

我不能推断出main中的buffer是否允许重用之前被class Test的临时对象占用的内存。根据标准自动存储(3.7.2/1)必须至少持续到块结束。

我找不到强制临时对象使用自动存储的措辞,除了6.6/2,其中描述了一个跳转语句,并说在退出作用域时[…],对于所有具有自动存储持续时间(3.7.2)的构造对象(命名对象或临时对象)调用析构函数(12.4),这似乎暗示临时对象使用自动存储。

临时需要使用自动存储吗?在main的局部变量在上面的代码允许重用内存以前占用的临时或它应该使用不同的存储?

临时对象的生存期(除非绑定到const&)延伸到完整表达式的末尾。在您的情况下,main中的第一行。编译器允许重用相同的内存,但是否这样做是一个实现细节(即实现质量)

12.2 (class.temporary)

/3[…临时对象在求值的最后一步被销毁(词法上)包含创建点的完整表达式(1.9)。[…]

/4在两种上下文中,临时变量在与完整表达式末尾不同的位置被销毁。第一个上下文是当表达式作为定义对象的声明符的初始化项出现时。[…]

/5第二个上下文是当引用被绑定到临时对象时。

由于您不属于任何例外,因此Test临时属于第一类,并且作为第一行求值的最后一步被销毁

3.7.2/1特别讨论了块作用域变量。它们的存储空间必须持续整个块。然而,正如您所发现的,临时变量确实具有自动存储持续时间,但不是块范围变量

语法Test()创建一个临时。这与命名为:

的对象不同
Test iHaveAName;

一个命名对象有块持续时间;它会一直持续到街区结束。临时具有表达期限;当它所在的表达式结束时,它将被销毁。

因此,如果您执行Test().Process(), Test()临时将存在足够长的时间,以便Process()完成。

Test实例一直存在到;实例存在为止。未指定buffer是否重用Test实例使用的存储。据我所述,标准中没有任何内容阻止编译器重用该空间。

这是实现定义的。智能编译器可以通过对齐堆栈指针来优化代码,以便buffer可以重用内存。