【发布时间】:2021-10-11 04:33:33
【问题描述】:
在以下代码中:
#include <memory>
struct A;
std::unique_ptr<A> ok() { return {}; }
std::unique_ptr<A> error() { return std::unique_ptr<A>{}; }
Clang++ 编译好的 ok() 函数并拒绝 error() 函数并显示消息:
In file included from /opt/compiler-explorer/gcc-11.1.0/lib/gcc/x86_64-linux-gnu/11.1.0/../../../../include/c++/11.1.0/memory:76:
/opt/compiler-explorer/gcc-11.1.0/lib/gcc/x86_64-linux-gnu/11.1.0/../../../../include/c++/11.1.0/bits/unique_ptr.h:83:16: error: invalid application of 'sizeof' to an incomplete type 'A'
static_assert(sizeof(_Tp)>0,
演示:https://gcc.godbolt.org/z/M8qofYbzn
如果 C++ 中的默认构造对象返回和空大括号返回之间有任何真正的区别(一般情况下,以及在这种特殊情况下)?
【问题讨论】:
-
我认为这可能是一个clang错误,GCC和MSVC都不编译任何一个函数
-
有人能解释一下clang的
ok的优化程序集是做什么的吗?mov rax, rdi; mov qword ptr [rdi], 0; ret我怀疑 RVO 但不确定。 -
@Quimby 在
rdi中,调用者将返回对象的存储地址传递给ok。ok函数通过默认构造函数初始化此对象,该构造函数只是将其成员指针设置为nullptr。这对应于通过mov指令将其二进制表示设置为零字节。最后在rax中传回对象的地址。 -
同一问题的更多最小示例:godbolt.org/z/PWrvvGEbh.
-
@DanielLangr 谢谢你的解释,我的组装很糟糕。
标签: c++ incomplete-type