编译器和操作系统如何处理C ++中的const变量和const指针

时间:2016-11-14 15:46:01

标签: c++ pointers const

我理解这些带有“const”的技巧的抽象功能是为了安全问题,不要让程序员无意中改变事物,或者不要故意搞乱事情,或者在同一个项目的不同程序员之间意外混淆(如果我是错)。

不清楚的是:

  1. 如何通过编译器,操作系统(进程,线程),硬件(CPU,RAM)相关等来实现此承诺(不变) - 即“整个系统如何'标记'此单元格以这种特殊方式对待“。
  2. 在(C / C ++)代码中使用“const”是否会降低性能,对于效率极高的应用程序而言,是否依赖于编译器(如果是 - 请说明它的作用)?

5 个答案:

答案 0 :(得分:7)

立即回答您的两个问题: const永远不会降低性能,如果它会提高性能。这是因为当声明变量const时,允许编译器做出某些假设。它们无法更改,因此编译器可以使用它来优化代码,方法是重构部分consts或将这些consts的值添加到只读数据段,从而加快查找速度。

const_castconst离开(向编译器说谎),而数据存储在只读段中并尝试覆盖它将导致未定义的行为,这就是编译器可以依赖的原因程序员不这样做,因此可以提高速度。

编译器是唯一负责优化此部件的编译器,而不是任何&#34; 操作系统(进程,线程),硬件(CPU,RAM)&#34; < / p>

答案 1 :(得分:4)

  

我理解这些使用“const”的技巧的抽象功能是出于安全问题

嗯,const ness不是一个技巧,从通常使用短语的意义上讲它不是安全问题

  

......不要让程序员无意中改变一切......

是的,const告诉编译器 - 以及其他开发人员,包括你未来的自己 - 你没有打算来改变某些东西

  

......或者不要故意搞乱......

不,因为您可以简单地使用const_cast来绕过它(底层对象真正可变)。你不能意外地

  

......如何通过编译器实现这一承诺(不变)......

就是这样。这就是一切。编译器拒绝编译使const个对象变异的代码。如果变异const对象的代码无法编译,则不需要在运行时完成任何操作,也没有任何内容。

根据您的操作系统和硬件平台,有其他保护措施禁止写入您的进程无法更改的内存区域:例如,参见UNIX世界的SEGV,这通常是由您的内存地址映射硬件和操作系统协同执行。

这些运行时概念并不直接用语言表达,尽管它们确实会影响语言在给定平台上的实现方式。

  

...在(C / C ++)代码中使用“const”会降低性能......

不,const通常用于更清楚地表达代码的行为方式,而这些额外信息有时允许编译器进行更多优化。我想不出一个明显的原因,为什么它会让任何东西变慢,除非它强迫其他方面可以避免的副本。

答案 2 :(得分:2)

您错误地认为这是出于安全原因:实际上const关键字除了编译器之外没有强制执行。甚至可以命令编译器通过const - 强制转换忽略const关键字。

因此,在运行时没有与const关联的性能考虑因素(编译时可能会在编译时使用它来以不同方式优化代码)。

答案 3 :(得分:2)

Herb Sutter的article回答了你的大部分问题。

当变量为const时,编译器会假定该范围内的变量未被更改,并使用该信息来优化代码。

任何修改它的尝试都会导致未定义的行为:

  

除了可以修改声明为mutable(7.1.1)的任何类成员,   任何在其生命周期(3.8)结果中修改const对象的尝试   在未定义的行为中。

答案 4 :(得分:1)

  

如何通过以下方式实现这一承诺(不变)   编译器,操作系统(进程,线程),硬件(CPU,RAM)   相关等 - 即“整个系统如何标记”要处理的这个细胞   这种特殊的方式“。

const强制执行只读合同,并且在编译时始终会捕获违反该合同的正确(标准符合代码)代码;除了const_cast

编译器通常非常了解其目标体系结构。正确使用const可以帮助它构建以特殊方式生成的代码,以提高安全性可能速度。注意:除非您的编译器坏了,否则const永远不会降低速度。

const个对象可以保存在只读内存中,也可以保存在可以标记为只读的特殊内存中(这会强制执行一种硬件安全形式,在将内存标记为只读后尝试写入将触发访问冲突异常。

  

在(C / C ++)代码中使用“const”会降低性能吗?   非常高效的应用程序,它是否依赖于编译器(如果   是的 - 请说明它的作用)?

不,它没有。如果是这样,那个编译器就会出错。