2016-08-20 8 views
3

ヘッダーファイルをPointXYZRGBAI.hに作成してLidarFile.cppとcore.cpp、エラーが複数のファイルで使用されるヘッダーファイル内の構造体の宣言により、アーキテクチャx86_64の重複シンボルが発生する

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 

とヘッダを発生するエラーが

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

ある文句ているように見えると私はメモリの位置合わせのための私のヘッダ定義構造体でEIGEN_ALIGN_16を使用します。ヘッダーガードが複数のインクルードを防止する必要がある場合、EIGEN_ALIGN_16は重複したシンボルになるのはなぜですか?説明をありがとうございます。

+2

良い答えに加えて、あなたの 'endif'はヘッダファイルの末尾になければなりません。そうでなければ役に立たないからです。 – Phil1970

+0

'ヘッダ'ファイルは通常、宣言(型と名前、別名インタフェース)のみを持っています。定義(実装のすべての詳細)は通常、実装ファイルの末尾に.cまたは.cppを付けて使用します。 –

答えて

3

ヘッダーガードは、1つのコンパイル単位(.oファイル)に複数のシンボルを含めることを防ぎます。しかし、ヘッダーファイルに実際の変数が宣言されているため、このヘッダーを含む各コンパイル単位には変数のコピーが作成されます。これは、シンボルを含む複数のオブジェクトファイルをリンクするまでは問題ありません。だからこそ問題はldによって報告され、gccでは報告されません。

より良いアプローチは、変数宣言をコンパイル単位(.cまたは.cppファイルの1つ)に入れ、ヘッダーファイルのexternを使用してその単一インスタンスを参照することです。

これはシニアソフトウェア開発者でさえも問題を引き起こします。

3

ザ・ガードを含む、同じ.cppファイル内の複数の介在を防止します。

ただし、複数の.cppファイルに含めることになります。そのヘッダーはオブジェクト(EIGEN_ALIGN_16)を定義するので、それは両方に含まれ、リンカーは2つの重複する定義があると不平を言うでしょう。

関連する問題