gcc: multiple definition of

/home/tace/openav/source/SeamlessMessage/CPaoFlt.o: In function CPaoFlt::get_m_strPrmair() const':<br></br>CPaoFlt.cpp:(.text+0x0): multiple definition ofCPaoFlt::get_m_strPrmair() const'

/home/tace/openav/source/SeamlessMessage/CPaoFlt.o:CPaoFlt.cpp:(.text+0x0): first defined here

gcc在编译过程中报函数重复定义(multiple definition of)的错误,主要有以下几点:

1) 在头文件中定义了变量或者函数,而非声明。譬如对于 foobar.h,

1 int foo = 10;
2 int bar()
3 {
4     return 10;
5 }

当foobar.h 被同一 .c 文件多次引用时(可能是间接多次引用),编译生成相应的 .o 文件,链接时候会报 foo bar 重复定义。

一个可能想到的方法是在头文件中加入宏定义,防止头文件被重复引用,如:

1 #ifndef FOOBAR_H__
2 #define FOOBAR_H__
3 int foo = 10;
4 int bar()
5 {
6  return 10;
7 }
8 #endif /* FOOBAR_H__ */

如果你只有一个 .c 文件,你可能得到一个可以运行的程序。但如果你有两个或以上的 .c 文件引用 foobar.h ,譬如 test1.c test2.c 引用了 foobar.h,则gcc -o a.out test1.c test2.c,链接时仍会报重复定义错误。

解决方法:在头文件中只声明函数、变量;对于 c++ 中的 inline 函数,在头文件中定义(编译的时候,inline 函数展开需要用到)。

对于 foobar.h 可以这样修改,为 .h 文件建立相应的 .c 文件,.h 文件中声明函数 .c 文件中定义函数,变量面前加修饰符 extern。

1 /** foobar.h **/
2 #ifndef FOOBAR_H__
3 #define FOOBAR_H__
4 extern int foo;
5 int bar();
6 #endif /* FOOBAR_H__ */
1 /** foobar.c **/
2 int foo = 10;
3 int bar()
4 {
5     return 10;
6 }

另外 static 修饰符也可以限制变量、函数的作用域,不过和本文无关了。

2) 在链接时,使用命令 gcc -o foobar main.o foobar.o foobar.o,你可能会想,怎么可能写出这样愚蠢的命令,但如果工程很大,.o 文件很多的时候,foobar.o 在不经意的时候被重复引用。如在 makefile 中:

FOO_OBJ = foo1.o foo2.o foo3.o foobar.o

BAR_OBJ = bar1.o bar2.o bar3.o foobar.o

foobar : main.o $(FOO_OBJ) $(BAR_OBJ)

gcc -o foobar main.o $(FOO_OBJ) $(BAR_OBJ)

错误出现了,而且很难查出来,特别是在维护别人程序的时候。本人不幸的花了两天时间才找到原因,虽然很早的时候也怀疑过这个问题,结果因为大意忽略过去了。这样修改就可以了:

foobar : main.o $(FOO_OBJ) $(BAR_OBJ)

gcc -o $@ $^

啊哈,终于知道 makefile 为什么要设置 $^ 这个变量了:) (注:$^ 所有不重复依赖文件,以空格分开)

在 gcc 编译的时候,加入 -Xlinker -zmuldefs 选项,但这只是强制编译器做些手脚,程序的错误仍没被改正。-Xlinker 告诉gcc将其后的选项-zmuldefs传给链接器ld,也就是强制让链接器忽略重复定义。
原文链接: https://www.cnblogs.com/9sheng/archive/2010/11/17/2684256.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17505

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午6:06
下一篇 2023年2月7日 下午6:06

相关推荐