欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

C++中的inline使用误区

程序员文章站 2024-03-23 14:20:46
...

缘由

老代码出现新问题,链接时出现问题。

/tmp/ccODJt0B.o: In function `main':
b.cpp:(.text+0x15): undefined reference to `A::GetAttr(int)'
collect2: error: ld returned 1 exit status

复现

简化代码复现如下:

//a.h
struct A
{
public:
int GetAttr(int i);
};

//a.cpp
#include "a.h"
inline int A:: GetAttr(int i)
{
        return 0;
}
//b.cpp
#include "a.h"
int main()
{
 A a;
 a.GetAttr(0);
 return 0;
}
//gcc  -o a.o -c a.cpp
//gcc  -o b  b.cpp a.o

分开实现实现,为了提高性能,直接加inline措施不正确。如果函数长期没有使用,不会报错,遇到使用时会出现上述的链接错误。
以下两种方式都不正确:

  • 情况1: a.h加inline, a.cpp也加inline: b.cpp看到的GetAttr声明为inline,所以要求GetAttr必须定义在b.o内,即违反了cpp手册中如下要求:
    The definition of an inline function or variable (since C++17) must be present in the translation unit where it is accessed (not necessarily before the point of access).
  • 情况2: a.cpp加inline, .h不加, b.cpp看到的GetAttr声明非inline,但是a.cpp里实现的GetAttr实际为inline,因此违反了cpp手册里如下要求:
    An inline function or variable (since C++17) with external linkage (e.g. not declared static) has the following additional properties:
    It must be declared inline in every translation unit.
    即a.cpp里的GetAttr实际是inline function, 且不是static,所以必须在每个.o的视角中都是声明为inline,但是实际上b.cpp看到的是声明为非inline的

小结

inline 必须实现在头文件,对引用可见。