Max*_*axB 7 c c++ performance gcc g++
const声明是否有助于编译器(GCC)生成更快的代码,或者它们仅对可读性和正确性有用吗?
Zed Shaw认为const在C/C++中无用或过度使用:
接下来是const的所有奇怪的魅力.由于一些奇怪的原因,C++喜欢让你在声明的每个部分都使用const,但是我得到与C相同的最终结果:调用一个函数.(......)
(来自:http://librelist.com/browser//mongrel2/2010/7/15/c-verses-c++/#770d94bcfc6ddf1d8510199996b607dd)
Kon*_*lph 11
是.这是一个具体的例子.const可以通过const&而不是通过值传递参数(这可能需要昂贵的副本).重要的是要意识到传递的替代const&方法不是通过 - &因为后者不允许临时绑定.所以,例如,这段代码:
auto result = foo{1} + foo{2} + foo{3};
Run Code Online (Sandbox Code Playgroud)
可以打电话foo operator +(foo const&, foo const&)但可能不打电话foo operator +(foo&, foo&).
这样,const有助于避免复制.
但一般来说,这const是一种确保正确性的工具,而不是帮助优化.
无论哪种方式,Zed Shaw都不知道他在说什么.顺便说一下,他的其余咆哮同样被误导了.
不,const不会帮助编译器编写更快的代码。Const是用于const正确性,而不是优化。
C ++标准说const不能修改项目,但也说const_cast应从const对象中删除修改器并使它可写(除非它位于实际的只读存储器中,在这种情况下行为是未定义的)。因此const,通常这并不意味着目标变量不会更改。
我只能想到这两个非常狭窄的场景,它们const产生的代码比没有它产生的代码快:
static)的全局变量,并通过引用或指针传递给在不同转换单元(不同文件)中定义的函数。在这种情况下,如果未标记,编译器将无法取消对其的读取const;extern)的全局变量。const extern可以在定义它的文件内忽略对a的读取(但无其他地方)。当const应用于全局变量时,允许编译器假定该值永远不会改变,因为它将把它放置在只读内存中,这意味着如果程序尝试对其进行修改,则表示未定义的行为,并且编译器作者喜欢依赖对不确定行为的威胁,以使代码更快。
请注意,这两种情况仅适用于全局变量,这可能只占程序中很小一部分的变量。然而,就其优点而言,它const意味着static在C ++中是全局级别的(在C中不是这种情况)。
上面有人说,使用const可以使代码更快,因为可以使用const引用。我在这里争论说,使代码更快的原因是引用的使用,而不是的使用const。
就是说,我仍然相信这const是一把非常锋利的刀,您无法用它割伤自己,我建议您在适当的时候使用它,但出于性能方面的考虑,不要使用它。
一般来说,const由于多种原因,方法、引用和指针的修饰符不能用于优化代码。第一个是const,在这些情况下,修饰符不能保证底层数据不会改变,它只是让修改它变得更加困难。这是一个经典的例子
void M(const C& p1, C& p2) {
cout << p1.field << endl;
p2.Mutate();
cout << p1.field<< endl;
}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,很可能p1.field在此代码中进行了修改。最明显的情况是p1和p2引用相同的值。
C local;
M(local, local);
Run Code Online (Sandbox Code Playgroud)
因此编译器在这里无法进行真正的优化。该const参数与非常量参数同样危险。
它无法真正优化的另一个原因是任何人都可以在 C++ 中使用const_cast.
class C {
public:
int field;
int GetField() const {
C* pEvil = const_cast<C*>(this);
pEvil->field++;
return field;
}
};
Run Code Online (Sandbox Code Playgroud)
因此,即使您正在处理单个const引用,这些值仍然可以在幕后自由更改。