内联与 constexpr?

问题描述 投票:0回答:3

使用新的 C++11 标准,什么时候应该使用

inline
关键字而不是
constexpr
关键字?
constexpr
关键字是否比
inline
提供任何额外的优化,还是仅仅断言必须在编译时计算?

为什么

constexpr
在某些调用不恒定的情况下(例如在非
foo(x)
变量上调用
constexpr
)可以在 GCC 上工作?这是 GCC 中的错误还是它实际上是标准的一部分?

c++ optimization c++11 inline constexpr
3个回答
54
投票

断言某些东西可以在编译时计算是一种非常强大的优化。

内联仅通过将函数体复制/粘贴到调用站点来删除函数调用。函数体仍然需要执行,您只需节省函数调用的开销。

但是,如果您在编译时对相同的代码进行评估,那么它在运行时是“free”的。 但是

inline

constexpr
都不是
主要
关于优化。 inline的主要目的是抑制单定义规则,以便可以在标头中定义函数(这对模板很有用,顺便说一句,也使内联优化更容易)

之所以存在

constexpr

,是因为它在元编程中很有用,顺便说一句,它可以通过将更多计算移至编译时来帮助编译器更好地优化代码。

    


5
投票

C++0x将引入关键字constexpr,它允许用户 保证函数或对象构造函数是编译时的 常数。

如果函数超短,则将其标记为内联。如果编译时需要结果,则将函数标记为 constexpr。 (模板参数或数组大小)。我相信如果需要的话,一个功能可以兼而有之。

可以使用以下方式调用常量表达式函数或构造函数 非 constexpr 参数。就像 constexpr 整数文字一样 分配给非 constexpr 变量,constexpr 函数也可以 使用非 constexpr 参数调用,结果存储在 非 constexpr 变量。关键字只允许可能性 当表达式的所有成员都为时,编译时恒定性 常量表达式。

所以,GCC 在这方面并没有错。


-3
投票
inline

对编译器说“此函数在此翻译单元中的某处使用,并且对其他目标文件不公开”,但编译器很可能将函数体插入到调用者中。

constexpr
函数对编译器说“这个函数没有副作用,并且不依赖于参数本身以外的前提条件。”

constexpr

变量只是说“这个变量不会改变,它的数据可以包含在代码中。”。但是,如果您在静态或非静态函数中定义 constexpr 变量,则会有所不同,例如。如果

constexpr
数组是非静态的,gcc 只是将带有硬编码
mov
指令的数据移动到堆栈上,而
static constexpr
只是将数据存储在
.text
部分中。

不带 capture 分配给变量的 Lambda 表达式可以是 constexpr,而不是带 capture,因为如果不带 capture,它们不需要内存来保存捕获,并且它们的工作方式就像具有重载的空类

operator()

(但它们甚至可以转换为普通函数指针)用一个简单的一元加号:

+[]{}
)。
    

© www.soinside.com 2019 - 2024. All rights reserved.