使用新的C ++ 11标准,我应该何时在inline
关键字上使用constexpr
关键字? constexpr
关键字是否提供了超过inline
的任何其他优化,还是仅断言必须在编译时计算内容?
为什么constexpr
在某些调用不稳定的情况下会在GCC上工作,例如在非foo(x)
变量上调用constexpr
?这是GCC中的一个错误还是它实际上是标准的一部分?
答案 0 :(得分:33)
断言可以在编译时计算某些东西 是一种非常强大的优化。
内联只是通过将函数体复制/粘贴到调用站点中来删除函数调用。函数体仍然必须执行,只需节省函数调用的开销。
但是如果你在编译时对相同的代码进行评估,那么它在运行时就是 free 。
但inline
和constexpr
主要关于优化。 inline
的主要目的是抑制单定义规则,以便可以在标题中定义函数(这对模板很有用,顺便说一下,也可以使内联优化更容易)
并且constexpr
是因为它在元编程中很有用,顺便说一下,它可以通过将更多的计算转移到编译时来帮助编译器更好地优化代码。
答案 1 :(得分:3)
引用维基百科:
C ++ 0x将引入关键字constexpr,允许用户使用 保证函数或对象构造函数是编译时 恒定。
如果超短,则标记函数内联。如果在编译时需要结果,则将标记用作constexpr。 (模板参数或数组大小)。我相信如果需要,可以同时使用一个函数。
可以使用调用常量表达式函数或构造函数 非constexpr参数。就像constexpr整数文字一样 分配给非constexpr变量,constexpr函数也是如此 使用非constexpr参数调用,并将结果存储在 非constexpr变量。该关键字仅允许这种可能性 表达式的所有成员都是编译时常量 constexpr。
所以,GCC在这方面并不正确。
答案 2 :(得分:-2)
虽然inline
对编译器说'#34;这个函数在这个翻译单元的某处使用,并且不公开给其他目标文件",编译器很可能插入了函数的主体进入来电者。 constexpr
函数对编译器说"此函数没有副作用,并且不依赖于参数本身以外的前提条件。"
constexpr
变量只是说"此变量不会更改,其数据可以包含在代码中。"。但是,如果在函数static或nonstatic中定义constexpr变量,则会有所不同,例如。如果constexpr
数组是非静态数组,则gcc只会将带有硬编码mov
- 指令的数据移动到堆栈中,而static constexpr
只会将数据存储在.text
- 部分中。< / p>
没有捕获分配给变量的Lambda表达式可以是constexpr而不是捕获,因为没有它们不需要内存来保存捕获它们就像一个带有重载operator()
的空类一样工作(但它们甚至可以被转换使用简单的一元加号的简单函数指针:+[]{}
)。