37

使用新的 C++11 标准,何时应该使用inline关键字而不是constexpr关键字?constexpr关键字是否提供了任何额外的优化inline,或者它只是断言必须在编译时计算事物?

为什么constexpr在调用不是常量的某些情况下(例如调用foo(x)constexpr变量)在 GCC 上工作?这是 GCC 中的错误还是实际上是标准的一部分?

4

3 回答 3

44

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

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

但是,如果您在编译时评估相同的代码,它在运行时是免费的。

但两者inline都不constexpr主要关于优化的。inline的主要目的是抑制 one-definition-rule,以便可以在 headers 中定义函数(这对模板很有用,顺便说一下,也使内联优化更容易)

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

于 2011-08-18T20:59:06.010 回答
4

引用维基百科:

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

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

可以使用非 constexpr 参数调用常量表达式函数或构造函数。正如可以将 constexpr 整数文字分配给非 constexpr 变量一样,也可以使用非 constexpr 参数调用 constexpr 函数,并将结果存储在非 constexpr 变量中。只有当表达式的所有成员都是 constexpr 时,关键字才允许编译时恒定。

因此,GCC 在这方面并没有错。

于 2011-08-18T21:57:21.123 回答
-2

虽然inline对编译器说“此函数在此翻译单元的某处使用,并且对其他目标文件不公开”,但编译器很可能会将函数的主体插入调用者。constexpr函数对编译器说“这个函数没有副作用,并且不依赖于参数本身以外的先决条件。”

constexprvariables 只是说“这个变量不会改变,它的数据可以包含在代码中。”。但是,如果您在静态或非静态函数中定义 constexpr 变量,例如,它会有所不同。如果constexpr数组是非静态的,gcc 只是将带有硬编码 - 指令的数据移动mov到堆栈上,而static constexpr只是将数据存储在 - 部分中.text

没有捕获分配给变量的 Lambda 表达式可以是 constexpr,而不是捕获,因为没有它们不需要内存来保存捕获并且它们像重载的空类一样工作operator()(但它们甚至可以使用简单的一元转换为普通函数指针加:)+[]{}

于 2017-10-08T22:00:00.287 回答