Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaration of struct in header file used by multiple files causes duplicate symbol for architecture x86_64 [duplicate]

Even though I have included header guards on all my header files, when I create a header file PointXYZRGBAI.h and include it in both LidarFile.cpp and core.cpp, an error is generated

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

and the header the error seems to be complaining about is

#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);
}

and I use EIGEN_ALIGN_16 in my header defined struct for memory alignment. Why is EIGEN_ALIGN_16 a duplicate symbol if a header guard should prevent multiple inclusions? Thank you for the clarification.

like image 510
wfehrnstrom Avatar asked Aug 20 '16 03:08

wfehrnstrom


2 Answers

The header guards prevent multiple inclusion of the symbols in a single compilation unit (.o file). However, you've declared an actual variable in the header file, and therefore each compilation unit that includes this header will get its own copy of the variable. This isn't a problem until you link more than one object file containing the symbol together. That's why the problem is reported by ld and not gcc.

A better approach is to put the variable declaration inside a compilation unit (one of the .c or .cpp files) and use extern in the header file to reference that single instance.

This is a problem that trips up even senior software developers.

like image 62
kithril Avatar answered Oct 11 '22 14:10

kithril


The include guard prevents multiple inclusions within the same .cpp file.

However, you're including it in multiple .cpp files. Since that header defines an object (EIGEN_ALIGN_16), it will be included in both, and then the linker will complain that there are two duplicate definitions.

like image 41
Etienne de Martel Avatar answered Oct 11 '22 15:10

Etienne de Martel