【问题标题】:What is the difference between default constructed object return and empty braces return in C++?C++中默认构造的对象返回和空括号返回有什么区别?
【发布时间】: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 中,调用者将返回对象的存储地址传递给okok 函数通过默认构造函数初始化此对象,该构造函数只是将其成员指针设置为 nullptr。这对应于通过mov 指令将其二进制表示设置为零字节。最后在rax中传回对象的地址。
  • 同一问题的更多最小示例:godbolt.org/z/PWrvvGEbh.
  • @DanielLangr 谢谢你的解释,我的组装很糟糕。

标签: c++ incomplete-type


【解决方案1】:

都不应该编译。

结果对象is always potentially invoked的析构函数。在unique_ptr 的情况下,需要A 才能完成。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-10
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-30
    相关资源
    最近更新 更多