C++ inline关键字与g++报错undefined reference to …
今天在Linux下编写select网络模型的程序时, 对fd_set进行了简易的封装, 文件有3个, 分别为server.cpp FDSet.cpp FDSet.h, 发现使用g++命令编译时死活编译不过,
# 使用的命令
g++ main.cpp FDSet.cpp -o main -I ./
使用了很多方法报错均为
/usr/bin/ld: /tmp/ccpLMDcl.o: in function `main':
server.cpp:(.text+0x1df): undefined reference to `FDSet::clear()'
/usr/bin/ld: server.cpp:(.text+0x1ee): undefined reference to `FDSet::clear()'
/usr/bin/ld: server.cpp:(.text+0x205): undefined reference to `FDSet::add(int)'
/usr/bin/ld: server.cpp:(.text+0x28a): undefined reference to `FDSet::add(int)'
/usr/bin/ld: server.cpp:(.text+0x2b4): undefined reference to `FDSet::data()'
/usr/bin/ld: server.cpp:(.text+0x30a): undefined reference to `FDSet::contains(int)'
/usr/bin/ld: server.cpp:(.text+0x329): undefined reference to `FDSet::remove(int)'
/usr/bin/ld: server.cpp:(.text+0x467): undefined reference to `FDSet::contains(int)'
/usr/bin/ld: server.cpp:(.text+0x524): undefined reference to `FDSet::remove(int)'
collect2: error: ld returned 1 exit status
最后在https://www.runoob.com/w3cnote/cpp-inline-usage.html中看到建议inline关键字尽量放在头文件中, 于是将FDSet.cpp中的FDSet::函数的inline关键字全部去掉, 再次执行命令则编译通过.
因为内联函数要在调用点展开,所以编译器必须随处可见内联函数的定义,要不然就成了非内联函数的调用了。所以,这要求每个调用了内联函数的文件都出现了该内联函数的定义
inline要求每个调用内联函数的文件都出现该函数的定义,所以上述将inline-function置于.cpp中的行为就导致了编译器不能看到定义,只能看到.h文件中的声明,必须在连接时才能得知定义, 违反inline的规则.
但是由于.h文件被include预处理实质就是将.h代码引入.cpp中, 在编译时就相当于编译一个文件, 所以将inline函数定义在头文件中是可以正常编译执行的.
以前一直没有注意过这个问题, 因为以前要么一直编写的是模板类, 声明定义都要放到.h文件中, 要么编写函数直接就在.h声明加定义了, inline问题也就没有显现, 已经学习一年C++了竟然还出这种错误感觉好丢人!!
反思:
以前学习C++吧更多的精力放在了很多关于模板或新特性的奇技淫巧上, 一年竟然才学到了Linux网络编程, 不仅进度缓慢, 有些基础的基础也掌握的不好, 比如对于动静态库的了解基本还停留在名字上, 项目基本上没做过, 顶多的练习是用C++实现了一小套数据结构, 对于真实的项目根本无从下手, 需要反思调整一下思想和路线了!!