C++:使用 Makefile 和 object 声明的重复符号
C++: duplicate symbol using Makefile and object declaration
我在
中定义了一个结构
a.h
#IFNDEF
#define A_H
struct a_struct
{
int val;
int val_b;
}a;
#endif
并且 main.cpp 和 a.cpp 都包含 header
#include "a.h"
当我将 makefile 与以下内容一起使用时:
a.o: a.cpp a.h
g++ -std=c++11 -c $<
main.o: main.cpp a.h
g++ -std=c++11 -c $<
main: main.o a.o
g++ -std=c++ $^ -o $@
出现编译错误:
duplicate symbol '_a' in:
a.o
main.o
是否在a.cpp和main.cpp中重新定义了a
?
有没有办法在不改变a.h的情况下解决这个问题?
如果那不可能,我该如何更改代码?
提前谢谢你:)
问题是 a.h
都声明了数据类型 struct a_struct
和 都声明了 a
作为该类型的变量。每个包含 header 的翻译单元——例如,基于 a.cpp
的翻译单元和基于 main.cpp
的翻译单元将因此声明其自己的 a
,如果两个这样的翻译单元对同一个程序有贡献,然后导致未定义的行为。由于重复符号而被拒绝的程序是这种情况下 UB 的一种可能(并且相当普遍)的表现形式。
所以,
Is a being redefined in a.cpp and main.cpp?
是的。 a
的声明包含在每个源文件的翻译单元中,直接导致在每个源文件中定义 a
。从技术上讲,这些声明本身并不是定义,但这有点 hair-splitting.
Is there a way to resolve this issue without changing a.h?
如果程序被修改,使得其中只有一个翻译单元 #include
s a.h
,无论是直接还是间接,那么它就不会有多个 a
的定义(来自它现在有它们的来源)。目前尚不清楚这对您来说是否是一个可行的解决方案,但这似乎值得怀疑。
In case that's not possible, how may I change the code?
最简单的更改是从 a.h
中删除 a
的声明:
#ifndef A_H
#define A_H
struct a_struct
{
int val;
int val_b;
}; // <-- the main change is here
#endif
如果您确实需要一个类型为 struct a_struct
的外部变量 a
,那么您应该通过添加
在 header 中声明它 extern
extern struct a_struct a;
到header
和
在恰好一个 .cpp 文件中添加 a
的非(明确地)extern
声明:
struct a_struct a;
从它的名字来看,文件 a.cpp
似乎是后者的正确位置,但如果你不想修改它,那么你可以使用 main.cpp
代替。
我在
中定义了一个结构
a.h
#IFNDEF
#define A_H
struct a_struct
{
int val;
int val_b;
}a;
#endif
并且 main.cpp 和 a.cpp 都包含 header
#include "a.h"
当我将 makefile 与以下内容一起使用时:
a.o: a.cpp a.h
g++ -std=c++11 -c $<
main.o: main.cpp a.h
g++ -std=c++11 -c $<
main: main.o a.o
g++ -std=c++ $^ -o $@
出现编译错误:
duplicate symbol '_a' in:
a.o
main.o
是否在a.cpp和main.cpp中重新定义了a
?
有没有办法在不改变a.h的情况下解决这个问题?
如果那不可能,我该如何更改代码?
提前谢谢你:)
问题是 a.h
都声明了数据类型 struct a_struct
和 都声明了 a
作为该类型的变量。每个包含 header 的翻译单元——例如,基于 a.cpp
的翻译单元和基于 main.cpp
的翻译单元将因此声明其自己的 a
,如果两个这样的翻译单元对同一个程序有贡献,然后导致未定义的行为。由于重复符号而被拒绝的程序是这种情况下 UB 的一种可能(并且相当普遍)的表现形式。
所以,
Is a being redefined in a.cpp and main.cpp?
是的。 a
的声明包含在每个源文件的翻译单元中,直接导致在每个源文件中定义 a
。从技术上讲,这些声明本身并不是定义,但这有点 hair-splitting.
Is there a way to resolve this issue without changing a.h?
如果程序被修改,使得其中只有一个翻译单元 #include
s a.h
,无论是直接还是间接,那么它就不会有多个 a
的定义(来自它现在有它们的来源)。目前尚不清楚这对您来说是否是一个可行的解决方案,但这似乎值得怀疑。
In case that's not possible, how may I change the code?
最简单的更改是从 a.h
中删除 a
的声明:
#ifndef A_H
#define A_H
struct a_struct
{
int val;
int val_b;
}; // <-- the main change is here
#endif
如果您确实需要一个类型为 struct a_struct
的外部变量 a
,那么您应该通过添加
extern
extern struct a_struct a;
到header
和
在恰好一个 .cpp 文件中添加 a
的非(明确地)extern
声明:
struct a_struct a;
从它的名字来看,文件 a.cpp
似乎是后者的正确位置,但如果你不想修改它,那么你可以使用 main.cpp
代替。