zoukankan      html  css  js  c++  java
  • 【转】gcc: multiple definition of [转]

    原文链接:http://www.cnblogs.com/longdouhzt/archive/2012/07/03/2574071.html

    /home/tace/openav/source/SeamlessMessage/CPaoFlt.o: In function `CPaoFlt::get_m_strPrmair() const': CPaoFlt.cpp:(.text+0x0): multiple definition of `CPaoFlt::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,

    ------------- foobar.h ----------- int foo = 10; int bar() {  return 10; } ------------- foobar.h -----------

    当foobar.h 被同一 .c 文件多次引用时(可能是间接多次引用),编译生成相应的 .o 文件,链接时候会报 foo bar 重复定义。 一个可能想到的方法是在头文件中加入宏定义,防止头文件被重复引用,如:

    ------------- foobar.h ----------- #ifndef FOOBAR_H__ #define FOOBAR_H__ int foo = 10; int bar() {  return 10; } #endif /* FOOBAR_H__ */ ------------- 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。

    ------------- foobar.h ----------- #ifndef FOOBAR_H__ #define FOOBAR_H__ extern int foo; int bar(); #endif /* FOOBAR_H__ */ ------------- foobar.h -----------

    ------------- foobar.c ----------- int foo = 10; int bar() {  return 10; } ------------- foobar.c -----------

    另外 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 为什么要设置 $^ 这个变量了:)  (注:$^ 所有不重复依赖文件,以空格分开)

    3. 在 gcc 编译的时候,加入 -Xlinker -zmuldefs 选项,但这只是强制编译器做些手脚,程序的错误仍没被改正。-Xlinker 告诉gcc将其后的选项-zmuldefs传给链接器ld,也就是强制让链接器忽略重复定义。

    [转] http://blog.csdn.net/ninthing/article/details/6014088

    -------------------

    我把所有的全局变量写在一个global.h里,然后其他文件都include 了它 ,于是出现了 multiple   definition   of  .....
    (编译器 gcc )
    后来在网上搜到了很多类似的错误,大家各有各的烦心事。
    我的代码结构
    main.cpp #include "global.h"
    WinMain(....) { ... }
    file_1.cpp #include "global.h" ....
    file_2.cpp #include "global.h"
    ...
    由于工程中的每个文件都是独立的解释的, (即使头文件有 #ifndef _x_h .... #enfif   )
    在其他文件中只要包含了global.h 就会独立的解释,然后生成每个文件生成独立的标示符。在编译器连接时,就会将工程中所有的符号整合在一起,由于,文件中有重名变量,于是就出现了重复定义的错误。
    下面是解决方法:
    在global.c(或.cpp)  中声明变量,然后建一个头文件global.h 在所有的变量声明前加上extern ... 如 extern HANDLE ghEvent; 注意这儿不要有变量的初始化语句。
    然后在其他需要使用全局变量的 cpp文件中包含.h 文件而不要包含 .cpp 文件。编译器会为global.cpp 生成目标文件,然后连接时,在使用全局变量的文件中就会连接到此文件 。
    --------------------------------------------------------------------------------------------------------------------------------------
    今天Makefile的时候总是提示multiple definition of 的错误,也就是变量重复定义啦 可是我的程序里明明没有多个定义,搞不清楚怎么回事,我把头文件全部用头文件保护符 给限定了,可是还是没用,最后在网上搜了一下,解决方法其实很简单,就是把编译出错 提示最先定义的地方使用static限定词,限定为仅限在本文件中使用,就ok了

    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    本人备注:在遇见这类问题时,要注意几方面:1、不要重复包含头文件,这会造成重复定义 2、当多个cc文件必须包含同一个头文件时,对于static成员变量会出现重复定义。其中一种解决方法是在.h文件对该类变量只做声明,如extern int a,而在另一个要使用该变量的.CC文件做定义初始化。但这种解决方法对于多个.c文件都需包含该头文件的情况是不适用的,会出现错误,因为当无需该变量的.c文件编译到extern int a链接不到相应的定义或者链接到了但会出现重复定义,因为是static变量。所以在这种情况下,最好在.h文件的类中,删除该类成员变量,而只在需要该变量的.c文件做声明定义,如在a.c文件定义 static int a = 0.或者不在头文件删除该成员变量,而将多个包含该头文件的.cc文件合并成一个文件,不过这不是好的选择,对于代码的良好阅读性而言

  • 相关阅读:
    2018 ACM 网络选拔赛 徐州赛区
    2018 ACM 网络选拔赛 焦作赛区
    2018 ACM 网络选拔赛 沈阳赛区
    poj 2289 网络流 and 二分查找
    poj 2446 二分图最大匹配
    poj 1469 二分图最大匹配
    poj 3249 拓扑排序 and 动态规划
    poj 3687 拓扑排序
    poj 2585 拓扑排序
    poj 1094 拓扑排序
  • 原文地址:https://www.cnblogs.com/Sarah1127/p/4488009.html
Copyright © 2011-2022 走看看