假设没有编译器优化,这个对象会被创建多少次?
Assuming no compiler optimization, how many times will this object be created?
假设没有编译器优化。 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() 超出作用域时,它将 return 复制对象 s
到 main()。
3) 在 main() 中将值复制到对象 a
,因为由 func() 编辑的值 return 将是临时的。
我知道我在这里错了,因为我在 g++
中使用 -O0
进行编译,但是在覆盖构造函数后我只能看到一个创建。我想知道我哪里错了,为什么错了。
你这里有什么copy-elison。
Omits copy and move (since C++11) constructors, resulting in zero-copy pass-by-value semantics.
GCC 即使使用 -O0
选项也可以省略构造函数。这就是这里发生的事情。如果要专门防止省略,可以使用 -fno-elide-constructors
选项。
如果您使用此选项,对于 C++11,将有一次构造函数调用和两次移动构造函数调用。
如果您使用 C++17,在某些情况下可以保证复制省略,这里即使使用 -fno-elide-constructors
选项,也会有一个构造函数调用和一个移动构造函数调用。
C++17 引入了我引用的临时物化:
A prvalue of any complete type T can be converted to an xvalue of the same type T. This conversion initializes a temporary object of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object. If T is a class or array of class type, it must have an accessible and non-deleted destructor.
在这种情况下,对 contructor 的额外调用将变成 move 操作。在 C++17 之前,复制省略不是强制性的,编译器会通常 复制省略。据我所知,在您的情况下,编译器无论如何都会复制 elide(尝试使用 godbolt 并检查生成的程序集)。
要完全回答,调用构造函数并移动一次。
假设没有编译器优化。 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() 超出作用域时,它将 return 复制对象 s
到 main()。
3) 在 main() 中将值复制到对象 a
,因为由 func() 编辑的值 return 将是临时的。
我知道我在这里错了,因为我在 g++
中使用 -O0
进行编译,但是在覆盖构造函数后我只能看到一个创建。我想知道我哪里错了,为什么错了。
你这里有什么copy-elison。
Omits copy and move (since C++11) constructors, resulting in zero-copy pass-by-value semantics.
GCC 即使使用 -O0
选项也可以省略构造函数。这就是这里发生的事情。如果要专门防止省略,可以使用 -fno-elide-constructors
选项。
如果您使用此选项,对于 C++11,将有一次构造函数调用和两次移动构造函数调用。
如果您使用 C++17,在某些情况下可以保证复制省略,这里即使使用 -fno-elide-constructors
选项,也会有一个构造函数调用和一个移动构造函数调用。
C++17 引入了我引用的临时物化:
A prvalue of any complete type T can be converted to an xvalue of the same type T. This conversion initializes a temporary object of type T from the prvalue by evaluating the prvalue with the temporary object as its result object, and produces an xvalue denoting the temporary object. If T is a class or array of class type, it must have an accessible and non-deleted destructor.
在这种情况下,对 contructor 的额外调用将变成 move 操作。在 C++17 之前,复制省略不是强制性的,编译器会通常 复制省略。据我所知,在您的情况下,编译器无论如何都会复制 elide(尝试使用 godbolt 并检查生成的程序集)。
要完全回答,调用构造函数并移动一次。