C++ 标准允许(要求)编译器优化对复制构造函数的调用(在某些情况下)的原因是什么,即使它可能包含可观察到的副作用?
如果我没记错的话,“好像”规则已经允许编译器优化不必要的代码,只要生成的程序模拟标准中定义的抽象机器的可观察行为。
制定例外规则的动机是什么?它不会在语言中造成不一致吗?方便(或必要)吗?
C++ 标准允许(要求)编译器优化对复制构造函数的调用(在某些情况下)的原因是什么,即使它可能包含可观察到的副作用?
如果我没记错的话,“好像”规则已经允许编译器优化不必要的代码,只要生成的程序模拟标准中定义的抽象机器的可观察行为。
制定例外规则的动机是什么?它不会在语言中造成不一致吗?方便(或必要)吗?
绝大多数情况下,退货产生的副本将是不必要的成本。其余时间,预计复制构造函数的副作用将通过销毁副本来消除。诸如std::shared_ptr
在可以从外部观察到的副本上起作用,但在破坏时将其撤消。对象的复制构造极少会出现复制省略会遗漏的副作用。避免性能受到影响而给罕见情况带来不便是值得的。基本上从来没有问题。
复制省略可能意味着两种不同的东西。C++17 中的“强制复制省略”只是对纯右值的重新定义。
auto foo() { return std::mutex{}; }
这是合法且有意义的,因为std::mutex
就语言而言,函数内部还没有“创建”。让我们不要纠缠于这个案例。
在其他情况下,例如
auto bar()
{
std::vector v{1, 2, 3};
return v;
}
在检查复制/移动语义是否合法后,允许编译器省略复制/移动。
它不会在语言中造成不一致吗?
是的。但是很少有一种语言像 C++ 那样专注于一致性,复制省略正是因为 C++ 重视一致性而脱颖而出。这种妥协是为了获得巨大的好处:我们不希望人们担心编写函数的性能开销。
as-if 规则有时在理论上足以生成高效的代码,但在实践中通常非常困难。编译器在最长时间内无法优化它
delete new int;
对人类来说可能是微不足道的。我们不想等到优化器完善后才开始编写函数。