为啥很少有人输入 const 正确的代码? const 正确的代码会编译得更好/更快吗? [关闭]

Posted

技术标签:

【中文标题】为啥很少有人输入 const 正确的代码? const 正确的代码会编译得更好/更快吗? [关闭]【英文标题】:Why few people type const-correct code? Will const-correct code compile better/faster? [closed]为什么很少有人输入 const 正确的代码? const 正确的代码会编译得更好/更快吗? [关闭] 【发布时间】:2011-08-04 20:06:41 【问题描述】:

非常经常将指针作为函数参数传递给只读参数(例如结构等)。例如在这个构造函数中:

Chunk::Chunk(const string& text, COLOR * background, COLOR * foreground);

我以前更喜欢这种方式(不是 const 正确的),因为我认为它更容易阅读。 但是,我开始觉得这很脏,而是这样做:

Chunk::Chunk(const string& text, const COLOR * const background, 
                          const COLOR * const foreground);

一开始可能很难理解,但直到你习惯它。我的问题:

为什么没有人做对? (我见过这样的小代码) 编译更好/更小/更快?

确实知道有什么区别,但我真的不在乎不同的语义,因为任何阅读代码的人都可以看到 args 是只读的。 (谁会改变指针地址?)

确实知道我可以使用引用来代替,但假设我不想(或者我使用纯 C 语言)。

【问题讨论】:

也许你应该写const string& text,除非你需要一份副本 我不同意。与我一起工作的大多数人都对我们代码的成本正确性非常严格。 我不认为,这确实是一个技术问题,为什么有人会写出糟糕的代码 两个const 修饰符做不同的事情;第一个限制函数修改对象,而第二个限制函数修改其主体内的参数。 const 正确代码不会比非 const 正确代码编译显着更好/更快。许多人无法编写 const 正确的代码,因为他们是懒惰、草率、过度自信的代码猴子。也就是说,有可能走得太远,在没有真正帮助的地方使用“const”。 【参考方案1】:

在您列出的示例中

Chunk::Chunk(string text, const COLOR * const background, 
                          const COLOR * const foreground);

您可能还应该通过const& 传递字符串,除非您故意想要该字符串的本地副本。另外,在我看来,颜色参数应该被声明为const COLOR * 而不是const COLOR * const。第二个const 只是表示该函数不会将backgroundforeground 指针重新指向本地其他一些内存块。它不会影响调用者,因此它是一个实现细节。因此,即使实现文件明确将它们列为const COLOR * const,标题中的原型也应为

Chunk::Chunk(string text, const COLOR *background, 
                          const COLOR *foreground);

【讨论】:

+1,另外,在第二个const:标准规定,在函数声明中,参数类型的常量从签名(这里的参数类型是COLOR const *)。 函数定义不同,它告诉编译器它应该在内部检查分配。【参考方案2】:

const 关键字是针对人类的,它非常强大。

查看http://www.gotw.ca/gotw/081.htm 了解有关 const 优化的更多信息。

【讨论】:

【参考方案3】:

我相信 const 的主要特性是编译时的正确性检查,性能提升更像是一个令人愉快的副作用。

【讨论】:

除了没有这样的效果。优化器甚至没有“看到”引用或指针的常量性,它只是在那个级别根本没有语义意义的东西。 const 正确性被设计为对程序员的帮助,而不是编译器……如果它对程序员有帮助,这也是 IMO 的问题,但那是另一回事了。【参考方案4】:

const 正确性有助于编译器生成更快的代码。例如,如果您将非常量指针传递给函数编译器可能会假定该函数已修改已引用的内存块。

编辑:(来自 Exceptional C++ Style 40 New Engineering Puzzles, Programming Problems, and Solutions)

将参数和/或返回值声明为 const 是否有助于编译器生成更优化的代码或改进其代码生成?

简而言之,不,它可能不会。

为什么或为什么不?

编译器在哪些方面可以做得更好?它可以避免参数或返回值的副本吗?不,因为参数已经通过引用传递,返回已经是引用。它可以将 x 或 someY 的副本放入只读存储器吗?不,因为 x 和 someY 都存在于其范围之外,并且来自和/或被给予外部世界。即使 someY 是在 f 自身内部动态分配的,它和它的所有权也会交给调用者。

但是,出现在 f 的主体中的代码可能会进行哪些优化呢?由于 const,编译器能否以某种方式改进它为 f 的主体生成的代码?

仅仅因为 x 和 someY 被声明为 const 并不一定意味着它们的位在物理上是 const。为什么不?因为任何一个类都可能具有可变成员或其道德等价物,即成员函数内部的 const_casts。实际上, f 本身的代码可能会执行 const_casts 或 C 风格的强制转换,从而将 const 声明变成谎言。

在一种情况下,说 const 确实可以表示某些东西,那就是当对象在定义时被设为 const。在这种情况下,编译器通常可以成功地将这些“真正的 const”对象放入只读内存,特别是如果它们是 POD,其内存映像可以在编译时创建,因此可以直接存储在程序的可执行映像本身中。这样的对象通俗地称为“ROM-able”。

人们普遍认为 const 正确性有助于编译器生成更紧凑的代码。是的,const 确实是个好东西,但是这个 Item 的重点是 const 主要是为人类服务的,而不是为编译器和优化器服务的。

【讨论】:

不是真的。 const 正确的代码使代码更容易维护,因为它记录了意图。 使用const 并没有太大的性能优势。另见Constants and compiler optimization in C++ -1:这是一个常见的误解。指针或引用的“const”声明不能帮助优化器,因为这没有说明被引用或指向的对象的 const 性(它是指针/引用的属性)。由 const 指针/引用引用或指向的对象确实可以合法地发生变异(例如因为别名),因此优化器不能对它做任何特殊假设。 gotw:81 => gotw.ca/gotw/081.htm @Alessandro,如果编译器正在进行全局优化,它不需要 const 关键字,因为它在全局范围内知道它是否改变

以上是关于为啥很少有人输入 const 正确的代码? const 正确的代码会编译得更好/更快吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

为啥这个错误代码仍然是 con.commit()

共享指针和 const 正确性

为啥 lambda auto& 参数选择 const 重载?

为啥 const char* 返回值丢失了两个字符?但是在返回之前打印正确的值[重复]

为啥“char*”可以指向“const char*”?

为啥在 Rust 中将 const 引用直接转换为可变引用无效?