【问题标题】:Is there any special reason why the move constructor is not elided in the snippet shown below?下面显示的代码段中没有省略移动构造函数是否有任何特殊原因?
【发布时间】:2015-09-27 19:37:27
【问题描述】:

gcc,clang 和 VS2015 在抛出对象a 之后,不会在下面的代码中省略对移动构造函数的调用。在我看来,§8.12[class.copy]/31 (N4140) 的要点 (31.2) 中建立的条件已经满足。

#include <iostream>

struct A
{
    A() { std::cout << "Default ctor " << '\n'; }
    A(const A& a) { std::cout << "Copy ctor" << '\n'; }
    A(A&& a) { std::cout << "Move ctor" << '\n'; }
    ~A() { std::cout << "Destructor " << '\n'; }
};

int main()
{
    try
    {
        A a;
        throw a;
    }
    catch(A& a) { std::cout << "Caught" << '\n'; }
}

注意a 是一个左值,但根据§12.8/32,重载决议 首先执行为副本选择构造函数,就好像对象是由右值指定的一样。也就是说,调用移动构造函数是可以的。如果你删除上面移动构造函数的定义,复制构造函数会被调用,但同样,它不会被忽略!

我知道标准没有强制要求复制省略,但我很想知道是否有任何特殊条件可以证明上述三个编译器在这个特定示例中避免了这种优化这一事实。

gcc 的示例输出,来自上面的链接:

g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out

默认演员

移动器

析构函数

抓到

析构函数

【问题讨论】:

  • 它走在非凡的道路上,谁在乎呢?等效的happy path 完全优化
  • 我认为这是关于如果局部变量的构造有副作用则不能省略的措辞。不确定是否真的存在冲突,但作为简单的规则,它们可能对编译器有效地发生冲突。
  • @Cheersandhth.-Alf:复制省略是明确允许的,这样即使有副作用,编译器也能做到。
  • @DietmarKühl:不,我不是在谈论移动构造函数的副作用。
  • @DietmarKühl VS2015 即使在禁用优化的情况下也总是进行复制省略。我不知道有关 gcc 和 clang 的详细信息。但是您可以在上面提供的链接中验证 gcc 中使用的编译器开关,

标签: c++ exception c++14 copy-elision


【解决方案1】:

根据 12.8 [class.copy] 第 31 段,第二个项目符号可以省略被抛出的局部变量的副本:

throw-expression 中,当操作数是非易失性自动对象(函数或 catch 子句参数除外)的名称时,其范围不超出最里面 附上try-block(如果有的话),从操作数到异常对象(15.1)的复制/移动操作可以通过将自动对象直接构造到异常对象中来省略

似乎没有一个编译器使用这种优化。一个原因可能是它根本不值得这样做,因为最好将精力花在其他优化上。我认为标准中没有任何内容禁止这种优化。

【讨论】:

  • 不这样做的一个实际原因是,这可能重新排序副作用,其中局部变量的构造所做的事情以及 throw 之前的后续语句所依赖的东西被移动了投掷。
  • C++11 §3.7.3 中的相关标准,指出可以消除本地对象(及其构造的副作用,以下语句可能依赖),"如果具有自动存储持续时间的变量具有初始化或具有副作用的析构函数,则不应在其块结束之前将其销毁,即使看起来未使用也不应作为优化消除,除非 a类对象或其复制/移动可以按照 12.8 中的规定消除".
  • 哇,我很惊讶这个案子有一个明确的规定。很好的发现。
  • 缺陷报告887 显示,由于原件的不安全性,采用了当前措辞。由于仍然存在极端的不安全性(重新排序副作用),这可以说是标准中的一个缺陷。一个简单的解决方案是简单地放弃项目符号点,因为可以在需要时明确地进行移动。但是我没有直接看到任何关于它的缺陷报告。
猜你喜欢
  • 2019-08-08
  • 2015-09-30
  • 2020-06-20
  • 2012-08-30
  • 2023-03-03
  • 1970-01-01
  • 2015-01-30
  • 1970-01-01
  • 2019-10-23
相关资源
最近更新 更多