const 在 C/C 中提供了什么样的优化?

新手上路,请多包涵

我知道,出于可读性原因,您应该在通过引用或指针传递参数时尽可能使用 const 关键字。如果我指定参数是常量,编译器是否可以进行任何优化?

可能有几种情况:

功能参数:

常量参考:

 void foo(const SomeClass& obj)

常量 SomeClass 对象:

 void foo(const SomeClass* pObj)

以及指向 SomeClass 的常量指针:

 void foo(SomeClass* const pObj)

变量声明:

 const int i = 1234

函数声明:

 const char* foo()

每个都提供什么样的编译器优化(如果有)?

原文由 UnTraDe 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.1k
2 个回答

资源

情况1:

当您在程序中声明 const 时,

 int const x = 2;

编译器可以通过不为这个变量提供存储来优化这个 const ;相反,它可以添加到符号表中。因此,后续读取只需要间接进入符号表,而不是从内存中获取值的指令。

注意:如果您执行以下操作:

 const int x = 1;
const int* y = &x;

那么这将强制编译器为 x 分配空间。因此,对于这种情况,这种优化程度是不可能的。

函数参数方面 const 表示函数中没有修改参数。据我所知,使用 const 并没有显着的性能提升;相反,它是确保正确性的一种手段。


案例二:

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

 const Y& f( const X& x )
{
    // ... do something with x and find a Y object ...
    return someY;
}

编译器可以做得更好吗?它可以避免参数或返回值的副本吗?

不,因为参数已经通过引用传递。

它可以将 x 或 someY 的副本放入只读存储器吗?

不,因为 xsomeY 都在其范围之外并且来自和/或被给予外部世界。即使 someYf() 本身内动态分配,它和它的所有权都交给调用者。

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

即使调用 const 成员函数,编译器也不能假定对象 x 或对象 someY 的位不会改变。此外,还有其他问题(除非编译器执行全局优化):编译器也可能不确定没有其他代码可能具有非常量引用,该引用将同一对象别名为 x 和/或 someY ,以及在 f(); 执行期间是否可能偶然使用对同一对象的任何此类非常量引用,并且编译器甚至可能不知道真实对象是否 xsomeY 只是引用,实际上首先声明为 const 。


案例3:

 void f( const Z z )
{
    // ...
}

这里面会不会有优化?

是的,因为编译器知道 z 确实是一个 const 对象,即使没有全局分析,它也可以执行一些有用的优化。例如,如果 f() 的主体包含类似 g( &z ) 的调用,编译器可以确定 --- z --- 的非可变部分在致电 g()

原文由 ravi 发布,翻译遵循 CC BY-SA 4.0 许可协议

SomeClass* const pObj 创建一个指针类型的常量对象。不存在更改此类对象的安全方法,因此编译器可以例如将其缓存到仅读取一次内存的寄存器中,即使其地址已被占用。

其他的没有特别启用任何优化,尽管 const 类型上的限定符会影响重载分辨率,并可能导致选择不同且更快的函数。

原文由 Ben Voigt 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题