constexpr是否意味着内联?

Vin*_*ent 89 c++ inline standards-compliance constexpr c++11

考虑以下内联函数:

// Inline specifier version
#include<iostream>
#include<cstdlib>

inline int f(const int x);

inline int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}
Run Code Online (Sandbox Code Playgroud)

和constexpr等效版本:

// Constexpr specifier version
#include<iostream>
#include<cstdlib>

constexpr int f(const int x);

constexpr int f(const int x)
{
    return 2*x;
}

int main(int argc, char* argv[])
{
    return f(std::atoi(argv[1]));
}
Run Code Online (Sandbox Code Playgroud)

我的问题是:说明constexpr符是否意味着说明inline符,如果一个非常量参数传递给一个constexpr函数,编译器将尝试inline该函数,就像说明inline符被放入其声明一样?

C++ 11标准能保证吗?

Jer*_*fin 127

是([dcl.constexpr],C++ 11标准中的§7.1.5/ 2):"constexpr函数和constexpr构造函数是隐式内联的(7.1.2)."

但是请注意,该inline说明符真的有在编译器是否有可能扩大一个内联函数或不小的(如果有的话)的影响.但是,它会影响一个定义规则,从这个角度来看,编译器需要遵循constexpr函数的相同规则作为inline函数.

我还要补充一点,不管constexpr暗示如何,C++ 11中的函数inline规则constexpr要求它们足够简单,以至于它们通常是内联扩展的良好候选者(主要的例外是递归的).然而,从那时起,规则逐渐变得松散,因此constexpr可以应用于更大,更复杂的功能.

  • @KerrekSB`constexpr`函数可能在编译时进行评估.但是,C++ 14标准中充斥着很可能在运行时被调用的标准.例如:`std :: array <T,N> :: at` (10认同)

Cir*_*四事件 7

constexprinline表示非静态变量(C ++ 17内联变量)

考虑到C ++ 17内联变量,虽然constexpr确实暗示inline了函数,但对于非静态变量没有影响。

例如,如果您以我发布于以下内容的最小示例为例:内联变量如何工作?并删除inline,仅保留constexpr,则该变量将获得多个地址,这是内联变量应避免的主要事情。

constexpr 但是,静态变量是隐式静态的。

constexpr暗示inline功能的最小示例

/sf/answers/1007392431/所述,其主要作用inline不是内联而是允许函数的多个定义,标准引用位于:C ++头文件如何包含实现?

我们可以通过玩以下示例来观察到这一点:

main.cpp

#include <cassert>

#include "notmain.hpp"

int main() {
    assert(shared_func() == notmain_func());
}
Run Code Online (Sandbox Code Playgroud)

notmain.hpp

#ifndef NOTMAIN_HPP
#define NOTMAIN_HPP

inline int shared_func() { return 42; }
int notmain_func();

#endif
Run Code Online (Sandbox Code Playgroud)

notmain.cpp

#include "notmain.hpp"

int notmain_func() {
    return shared_func();
}
Run Code Online (Sandbox Code Playgroud)

编译并运行:

g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'notmain.o' 'notmain.cpp' 
g++ -c -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.o' 'main.cpp' 
g++ -ggdb3  -O0 -Wall -Wextra -std=c++11 -pedantic-errors  -o 'main.out' notmain.o main.o
./main.out
Run Code Online (Sandbox Code Playgroud)

如果我们inline从中删除shared_func,则链接将失败并显示:

multiple definition of `shared_func()'
Run Code Online (Sandbox Code Playgroud)

因为标头包含在多个.cpp文件中。

但是,如果我们将替换inlineconstexpr,那么它又可以工作了,因为constexpr也暗含了inline

GCC通过在ELF目标文件上将符号标记为弱来实现此目的:C ++头文件如何包含实现?

在GCC 8.3.0中测试。

  • 顺便说一句,声明为“constexpr”的静态类成员变量仍然是内联的。[cppreference.com](https://en.cppreference.com/w/cpp/language/inline): _声明 `constexpr` 的静态成员变量(但不是命名空间范围变量)隐式是一个内联变量。_ (7认同)
  • @ciro-santilli-trump-ban-is-bad 如果你有机会,你能更正你的说法“constexpr 静态变量是隐式静态的。”吗?我认为“静态”一词之一意味着“内联”。 (2认同)