gpt4 book ai didi

c++ - 为什么 C++ 编译器不在按值传递方案中优化更多的字符串结构?

转载 作者:太空狗 更新时间:2023-10-29 19:56:26 24 4
gpt4 key购买 nike

(本题灵感来自Nicolai Josuttis' CppCon 2017 talk。)

考虑以下源文件(对于一个对象,而不是一个完整的程序):

#include <string>

class C {
std::string s_;
public:
C(std::string s) : s_(s) { };
void bar();
};

void foo() {
std::string hello { "The quick brown fox jumped over the lazy dog" };
C c { hello };
c.bar();
}

及其compilation result on GodBolt .

即使使用 -O2(甚至使用 -O3),字符串构造函数似乎也被调用了三次。具体来说,构造s,仅用于构造s_,然后销毁。我的问题:

  • 是否允许编译器根据构造函数的参数简单地构造 s_,而不构造 s
  • 如果不是,是否允许编译器从 s 移动构造 s_,看看后者是如何未被使用的?
  • 如果前面的任何一个答案是"is"——为什么 gcc 和 clang 不这样做?
  • 如果 s 构造得当,编译器就不能避免构造 hello 吗,看看它怎么没有其他用处?或者至少摆脱它?

最佳答案

在 as-if 下,我确定您要求的大部分内容都可以完成,假设您进入链接时间并将 bar 设置为空并且从不覆盖新的任何地方。

但是,在 as-if 下,您的程序是一个空程序,它没有可观察到的效果。

根据抽象机的规则,不允许编译器从s 移动构造s_。如果您希望它被移动构造,std::move 它。

左值可以被视为右值的情况是有限且特定的,并且涉及 return x; 语句。这不是 return x; 语句。

因此您的代码必须s 复制到s_。很可能它还应该生成警告作为实现质量问题。

编译器不允许将 s 省略为 s_。有一些允许更激进的省略规则的提案。

但截至目前,只有在 as-if、纯右值或 return x; 语句下才允许省略。就好像消除真的很难用像分配这样复杂的东西来证明,大多数编译器都不会尝试。而且在目标文件生成时是不可能的,因为有人可以替换全局分配器。

想象一个全局分配器覆盖,它打印出完成了多少分配。然后使用那些“从未使用过”的对象,因为它们应该打印出它们所做的分配。

或者在 2 次分配后调用 exit 的全局分配器。产生的抽象机永远不应该调用 bar();如果我们消除您的额外对象,程序将不会按照标准要求运行。

关于c++ - 为什么 C++ 编译器不在按值传递方案中优化更多的字符串结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48666320/

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