gpt4 book ai didi

c++ - 平凡与非平凡类型的复制省略差异

转载 作者:行者123 更新时间:2023-12-01 14:23:07 30 4
gpt4 key购买 nike

当一个函数按值返回直接按值传递给另一个函数时,我正在检查普通和非普通可复制类型之间的复制省略。对于非平凡的情况,对象似乎是按预期直接传输的,但对于平凡的情况,似乎输出对象被复制到堆栈上以制作第二个函数的输入对象。我的问题是,为什么?

如果这是预料之中的,这令人惊讶,因为在这些函数之间更有效地传递了非平凡可复制类型。

来源:

struct Trivial_Struct
{
unsigned char bytes[ 4 * sizeof( void* ) ];
};

struct Nontrivial_Struct
{
unsigned char bytes[ 4 * sizeof( void* ) ];
Nontrivial_Struct( Nontrivial_Struct const& );
};

Trivial_Struct trivial_struct_source();
Nontrivial_Struct nontrivial_struct_source();
void trivial_struct_sink( Trivial_Struct );
void nontrivial_struct_sink( Nontrivial_Struct );

void test_trivial_struct()
{
trivial_struct_sink( trivial_struct_source() );
}

void test_nontrivial_struct()
{
nontrivial_struct_sink( nontrivial_struct_source() );
}

GCC 输出组件:
test_trivial_struct():
sub rsp, 40
mov rdi, rsp
call trivial_struct_source()
push QWORD PTR [rsp+24]
push QWORD PTR [rsp+24]
push QWORD PTR [rsp+24]
push QWORD PTR [rsp+24]
call trivial_struct_sink(Trivial_Struct)
add rsp, 72
ret
test_nontrivial_struct():
sub rsp, 40
mov rdi, rsp
call nontrivial_struct_source()
mov rdi, rsp
call nontrivial_struct_sink(Nontrivial_Struct)
add rsp, 40
ret

godbolt.org .我尝试了 GCC、Clang 和 MSVC; GCC 的程序集对我来说更容易阅读,但所有编译器似乎都为简单可复制的情况制作了类似的代码。

杂项:
  • 显然,如果我声明复制构造函数 ,我可能会意外地使 'Nontrivial_Struct' 实际上变得微不足道。内类定义为 Nontrivial_Struct( Nontrivial_Struct const& ) = default ;如果我添加 Nontrivial_Struct::Nontrivial_Struct( Nontrivial_Struct const& ) = default; 类定义那么它仍然是重要的。
  • 我可以将“4”更改为较大的值,例如“64”,但它仍然发生。

  • 猜测:
  • 这是与 C ABI 的向后兼容吗?
  • http://eel.is/c++draft/class.temporary#3有什么关系吗? ?
  • 最佳答案

    调用约定由 ABI 强制执行。 ABI 指定两个源函数的返回值都由调用者分配,并传递一个隐藏的指针。 ABI 指定平凡结构在堆栈上传递,非平凡结构通过隐藏指针传递。引用:x86-64C++ ABI。

    [class.temporary]/3 为实现提供了为参数和返回值创建临时变量的自由度,这使得观察到的行为正常。它没有强制要求。

    简单的结构是在堆栈中初始化的返回值,并且必须在堆栈上传递(都是因为 ABI)。有人可能会问,为什么它将结构从它在堆栈上的第一个位置复制到堆栈上的第二个位置?那个拷贝确实是不必要的。编译器可以做得更好。这是GCC bug .

    关于c++ - 平凡与非平凡类型的复制省略差异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60121533/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com