C++ 非平凡变量的常数正确性

C++ 非平凡变量的常数正确性,c++,copy-elision,C++,Copy Elision,(虽然没有关联,但有点启发) 我一直被告知(并且一直被告知)保持const-正确性,即使是对于短期变量也是有价值的良好实践,例如: const std::string a = "Hello world"; 而不是 std::string a = "Hello world"; 这: 更清楚地表达意图 确保变量是不可变的,因此将其传递给某个可能会更改它的函数会使编译器对您大喊大叫 可能会因为编译器优化而提高性能 尽管现代C++引入了复制删除,但已经允许编译器调用移动构造函数而不是复制构造函数

(虽然没有关联,但有点启发)

我一直被告知(并且一直被告知)保持
const
-正确性,即使是对于短期变量也是有价值的良好实践,例如:

const std::string a = "Hello world";
而不是

std::string a = "Hello world";
这:

  • 更清楚地表达意图
  • 确保变量是不可变的,因此将其传递给某个可能会更改它的函数会使编译器对您大喊大叫
  • 可能会因为编译器优化而提高性能
尽管现代C++引入了复制删除,但已经允许编译器调用移动构造函数而不是复制构造函数:

在以下复制初始化上下文中,可能会执行移动操作 用于替代复制操作:

(3.1) 如果
return
语句([stmt.return])中的表达式是使用 正文中声明的自动存储持续时间或 最内层封闭函数的参数声明子句或 lambda表达式,或

3.2) 如果
抛出表达式([expr.throw])的操作数是非易失性自动对象的名称(函数或catch子句除外)
参数),其范围不超出最内层
封闭
试块
(如果有)

这是否意味着当面对这种省略适用于的情况时,使用非默认复制/移动构造函数的
const
对象而不是增加时,实际上可能会有性能损失

这是否意味着使用非默认复制/移动构造函数的const对象实际上会有性能损失

可能是的。当返回本地对象时,constness将阻止使用引用规则所允许的移动构造。但是,在实践中可能不存在性能损失,因为无论变量是否为常量,NRVO都可能省略整个复制/移动


但是,NRVO并不能保证,也不一定总是可能的——或者只是没有启用(调试构建),所以在按值返回局部变量时使用非常量可能是值得的。

@Acorn当优化器还没有那么成熟时,我肯定看到编译器生成了比没有
const
更优化的程序集。(我认为这是C++之前的11次)现在的情况可能不是这样,因为优化器非常擅长发现数据是否被修改过,所以可能它不再被修改了,它只是一个古老的遗迹。(比如使用
inline
来提高性能)。不确定你的意思,当然我也无法证明,但这听起来像是codegen错误(即在不应该的情况下优化
const
)、非标准实现(相同)或错过优化(即不同时优化这两种情况)@Acorn如果您获取一个非常量对象的地址,并将非常量指针传递给另一个翻译单元中定义的函数,则优化人员必须假设该对象可能已被修改,并且以后必须通过内存访问该对象,对吗?如果对象是常量,那么将指向它的非常量指针传递到另一个TU不会阻止Optimizer在寄存器中缓存变量的值,因为它无法更改。我的推理是错误的吗?@Acorn这里有一个codegen的不同点:顺便说一句,
const
实际上可以提高性能:一个带有初始值设定项的
extern const
足够简单的对象(比如
int
),因为即使没有内部链接,编译器也可能利用标准中规定的值不允许更改的事实。