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