这里主要讲述inline关键字在CPP不同标准中的含义,用来指导我们编程。

参考链接:https://en.cppreference.com/w/cpp/language/inline

从C++17开始,inline的实际意义是:允许多次定义,而不是优先内联。

 

最初:inline用于将函数声明为一个内联函数(提示编译器进行优化)。

C++11中的变化:

  1. 声明有 constexpr 的函数是隐式的内联函数。
  2. 定义为delete的函数是隐式的内联函数,其定义可出现在多个“翻译单元”中。

P.s> 这里翻译单元的原文是 translation unit ,我们常见的 .cpp 文件就是一种翻译单元。

 

C++17中的变化:

  1. 允许修饰变量;当它用于修饰具有静态存储期的变量(静态类成员或命名空间作用域变量)时,将变量声明为“内联变量”。
  2. 声明为 constexpr 的静态成员变量(不得是命名空间作用域变量)是隐式内联变量。

 

在C++20之前(until C++20):

一个完全在 class/struct/union 中定义的函数,无论它是成员函数还是非成员友元函数,都隐式地成为内联函数。

 

从C++20开始(since C++20):

一个完全在 class/struct/union 中定义的函数,无论它是成员函数还是非成员友元函数,如果它附加到全局模块上,就隐式地成为内联函数。

P.s> 这里的模块指的是C++20的新概念,module.

 

内联函数 Or 内联变量(C++17) 具有以下属性:

  1. 内联函数 Or 内联变量的定义必须在访问它的翻译单元中是可访问的, 不一定要在访问点之前。
  2. 具有外部链接的内联函数 Or 内联变量具有如下额外属性:
    1. 内联函数 Or 内联变量可以在程序中拥有多次定义,只要所有的定义不出现在同一个翻译单元,且所有定义完全一致即可。
    2. 它必须在每个翻译单元中均被声明为inline
    3. 它在每个翻译单元中均拥有相同的地址

 

在内联函数中:

  1. 不同翻译单元中所有内联函数共享局部静态变量(static),或者说它们都引用了同一个对象。
  2. 所有函数定义中所定义的类型亦在所有翻译单元中相同。

P.s> 说实话第二点我没理解,它应该说的是参数类型 和 返回值类型完全一致?其实我觉得只需要认为不同翻译单元中的内联函数是同一个函数就行了。

 

从C++17开始对inline关键字含义的变化:

inline关键字最初的含义是:作为优化器的指示器,指明优先采用内联替换而非进行函数调用。

这样做的好处是:避免函数调用开销;

导致的问题是:更大的执行文件,因为函数体被复制了多次。

另外,因为inline关键字的含义是非强制的,所以编译器拥有对没有标识inline函数替换的自由,它也可以将标识了inline的函数做函数调用而非函数体替换。

这些优化选择不改变上述关于多个定义和共享静态变量的规则。

 

综上, 我们可以认为从C++17开始,inline的实际意义是:允许多次定义。而不是优先内联。

 

 

最后:

  1. 如果具有inline标识的函数和变量在不同的翻译单元(CPP文件)中定义不同,则行为未定义(此时应由不同编译器自己决定)
  2. inline 不能用于作用域块内部(函数内部) 的函数Or变量声明
  3. inline 不能重声明在翻译单元中已定义为非内联的函数Or变量
  4. 隐式生成的成员函数(比如构造函数)和任何在其首次声明为inline的成员函数,与任何其他在类定义中定义的函数一样是内联的。
  5. 内联变量消除了将 C++ 代码打包为唯头文件的库的主要障碍。
【C++标准】inline 说明符在不同标准中的含义
Tagged on:     
0 0 vote
Article Rating
订阅
提醒
0 评论
Inline Feedbacks
View all comments