多个文件使用的头文件中的结构声明导致架构 x86_64 的重复符号

use*_*261 4 c++ struct boost header eigen

尽管我在所有头文件中都包含了头文件保护,但当我创建头文件 PointXYZRGBAI.h 并将其包含在 LidarFile.cpp 和 core.cpp 中时,会生成错误

duplicate symbol _EIGEN_ALIGN_16 in:
    CMakeFiles/core.dir/core.cpp.o
    CMakeFiles/core.dir/LidarFile.cpp.o
ld: 1 duplicate symbol for architecture x86_64
Run Code Online (Sandbox Code Playgroud)

错误似乎抱怨的标题是

#define PCL_NO_PRECOMPILE

#ifndef POINTXYZRGBAI_H
#define POINTXYZRGBAI_H
#endif

#include <pcl/point_types.h>

struct PointXYZRGBAI{
  PCL_ADD_POINT4D;
  union{
    struct{
      float intensity;
      uint32_t rgba;
    };
    float data_c[4];
  };
  EIGEN_MAKE_ALIGNED_OPERATOR_NEW
} EIGEN_ALIGN_16;

POINT_CLOUD_REGISTER_POINT_STRUCT(PointXYZRGBAI,
                                  (float, x, x)
                                  (float, y, y)
                                  (float, z, z)
                                  (float, intensity, intensity)
                                  (uint32_t, rgba, rgba)
)

inline std::ostream& operator << (std::ostream& os, const PointXYZRGBAI& p){
  os << "(" << p.x << ", " << p.y << ", " << p.z << " - " << p.intensity << " - " << p.rgba << ")";
  return (os);
}
Run Code Online (Sandbox Code Playgroud)

我在我的头定义结构中使用 EIGEN_ALIGN_16 进行内存对齐。如果标题保护应防止多次包含,为什么 EIGEN_ALIGN_16 是重复符号?谢谢你的澄清。

kit*_*ril 5

头文件保护防止在单个编译单元(.o 文件)中多次包含符号。但是,您已经在头文件中声明了一个实际变量,因此每个包含该头文件的编译单元都将获得它自己的变量副本。除非您将包含该符号的多个目标文件链接在一起,否则这不是问题。这就是问题由 ld 而不是 gcc 报告的原因。

更好的方法是将变量声明放在编译单元(.c 或 .cpp 文件之一)中,并在头文件中使用 extern 来引用该单个实例。

这是一个即使是高级软件开发人员也会绊倒的问题。