假设没有编译器优化,则将创建多少次此对象

Assuming no compiler optimization, how many times will this object be created?

本文关键字:创建 多少次 对象 编译器 优化 假设      更新时间:2023-10-16

假设没有编译器优化。outputbuffer_s类型对象将被创建多少次?

#include <iostream>
#include <vector>
struct OutputBuffer_s {
    int encoded[10];
};
OutputBuffer_s func() {
    OutputBuffer_s s;
    return s;
}
int main() {
    OutputBuffer_s a = func();
}

最初,我已经假设了三遍。

1)当调用func()时,将在堆栈上创建对象s

2)当func()脱离范围时,它将返回对象 s的副本为main()。

3)将值复制到main()中的对象 a,因为func()返回的值将是一个临时。

我知道我在这里错了,因为我在g++中使用-O0编译,但是在覆盖构造函数后,我只能看到一个创建。我想知道我在哪里以及为什么错了。

您在这里拥有的copy-elison。

省略复制和移动(自C 11)构造函数,从而导致零拷贝传递语义。

GCC即使使用-O0选项也可以填充构造函数。这就是这里发生的事情。如果要专门防止ELINIS,可以使用-fno-elide-constructors选项。

如果您使用此选项,将会有一个构造函数调用和两个移动构造函数C 11。

请参阅此处的演示。

如果您使用C 17,则可以保证在某些情况下进行复制 - 恢复,即使使用-fno-elide-constructors选项,也会有一个构造函数调用,只有一个移动构造函数调用。

请参阅此处的演示。

c 17引入了我引用的临时物质化:

任何完整类型T的prvalue都可以转换为同一类型T的XVALUE。此转换通过以临时对象作为结果对象评估Prvalue的type t type t type t type对象,并产生一个并产生一个xvalue表示临时对象。如果t是类类型的类或数组,则必须具有可访问且非删除的破坏者。

在这种情况下,额外的呼叫 contructor 将成为移动操作。在C 17之前,该复制ELISION不是强制性的,编译器通常会通常复制Elide。据我所知,在您的情况下,编译器无论如何都会复制Elide(尝试Godbolt并检查制作的组装)。

要完全回答,一个呼叫构造函数和一个动作。