CLion编译C++项目时已添加对应源文件仍报undefined reference to `vec3::length() const`错误求助
解决
undefined reference to vec3::length() const 链接错误 这个问题的根源非常明确:你把inline函数的定义放在了.cpp文件中,而非头文件内。
在C++的规则里,inline函数的定义必须出现在每一个调用它的编译单元(简单来说就是每个用到这个函数的.cpp文件)中。当你在vec3.cpp里定义inline double vec3::length() const时,编译main.cpp的阶段,编译器只能看到vec3.h里的函数声明,看不到具体实现,它会默认这个函数在其他地方有外部链接的实现。但因为inline关键字的特性,链接器处理vec3.cpp时,不会保留这个inline函数的符号(inline函数默认是内部链接),最终就出现了链接时找不到符号的错误。
两种可行的解决方案:
方案1:把inline函数的定义移到头文件中
你可以直接把inline函数的实现写在vec3.h的类内部,或者类外部的头文件区域(记得保留inline关键字):
// vec3.h #ifndef RAY_TRACING_CPP_VEC3_H #define RAY_TRACING_CPP_VEC3_H #include <cmath> // 必须包含这个头文件,否则sqrt等函数会报错 struct vec3 { double x; double y; double z; vec3(double x, double y, double z) : x(x), y(y), z(z) {} vec3() : x(0.0), y(0.0), z(0.0) {} explicit vec3(double x) : x(x), y(x), z(x) {} // 直接在类内定义inline函数 inline double norm2() const { return x * x + y * y + z * z; } inline double length() const { return sqrt(norm2()); } inline double dot(const vec3& another) const { return x * another.x + y * another.y + z * another.z; } inline vec3 cross(const vec3& another) const { return { y * another.z - z * another.y, z * another.x - x * another.z, x * another.y - y * another.x }; } inline vec3 normalize() const { auto len = length(); return *this / len; // 这里注意:你还需要重载vec3与double的除法运算符,否则此处也会报错 } vec3 exp() const; vec3 pow(double param) const; }; #endif //RAY_TRACING_CPP_VEC3_H
之后修改vec3.cpp,只保留非inline的函数实现:
#include "vec3.h" #include <cmath> vec3 vec3::exp() const { return {std::exp(x), std::exp(y), std::exp(z)}; } vec3 vec3::pow(double param) const { return {std::pow(x, param), std::pow(y, param), std::pow(z, param)}; }
方案2:去掉inline关键字
如果你不想把函数定义放在头文件里,直接移除vec3.h和vec3.cpp中的inline关键字,让这些函数变成普通的外部链接函数:
// vec3.h // 移除所有inline关键字 double norm2() const; double length() const; double dot(const vec3& another) const; vec3 cross(const vec3& another) const; vec3 normalize() const;
// vec3.cpp // 同样移除inline关键字 double vec3::norm2() const { return this->x * this->x + this->y * this->y + this->z * this->z; } double vec3::length() const { return sqrt(norm2()); } // ... 其他函数同理移除inline
另外提醒:你的vec3::normalize()函数里用到了*this / len,但目前代码中没有重载vec3与double的除法运算符,这个后续也会触发编译错误,记得补充对应的运算符重载逻辑。
你的CMakeLists.txt配置是完全没问题的,已经正确包含了vec3.cpp,无需修改。
内容的提问来源于stack exchange,提问作者IceWired
相关产品推荐
相关产品推荐

