【问题标题】:Multiple definitions when compiling/linking [duplicate]编译/链接时的多个定义[重复]
【发布时间】:2012-12-11 22:36:18
【问题描述】:

可能重复:
Repeated Multiple Definition Errors from including same header in multiple cpps

我在编译第三方 src 时遇到以下错误:

.libs/lib_udf_la-udf.o:(.rodata+0x240): multiple definition of `SHIFT_TABLE'
.libs/lib_udf_la-hll.o:(.rodata+0x0): first defined here

项目是用自动工具设置的;我的Makefile.ag 引用了以下内容:

SOURCES = hll.c udf.c udf.h 
  • hll.c 引用 hll.h
  • udf.c 引用 hll.h
  • hll.h 有一些 const 像这样:
  • hll.h 有 #ifndef HLL_H ... #endif 来避免双重定义

    int const SHIFT_TABLE[1024] = {...}

我不明白我为什么要打多个定义,我猜这与链接步骤有关,但我已经很久没有涉足 C 语言了。

这是 cc/link 输出供参考:

make[1]: Entering directory `/home/mping/workspace/monetdb/MonetDB-11.13.5/sql/backends/monet5/UDF'
/bin/bash ../../../../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../../..  -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk  -DLIBUDF  -g -O2   -c -o lib_udf_la-hll.lo `test -f 'hll.c' || echo './'`hll.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c hll.c  -fPIC -DPIC -o .libs/lib_udf_la-hll.o
/bin/bash ../../../../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I../../../..  -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk  -DLIBUDF  -g -O2   -c -o lib_udf_la-udf.lo `test -f 'udf.c' || echo './'`udf.c
libtool: compile:  gcc -DHAVE_CONFIG_H -I. -I../../../.. -I. -I.. -I./.. -I../../../include -I./../../../include -I../../../common -I./../../../common -I../../../storage -I./../../../storage -I../../../server -I./../../../server -I../../../../monetdb5/modules/atoms -I./../../../../monetdb5/modules/atoms -I../../../../monetdb5/modules/kernel -I./../../../../monetdb5/modules/kernel -I../../../../monetdb5/mal -I./../../../../monetdb5/mal -I../../../../monetdb5/modules/mal -I./../../../../monetdb5/modules/mal -I../../../../monetdb5/optimizer -I./../../../../monetdb5/optimizer -I../../../../clients/mapilib -I./../../../../clients/mapilib -I../../../../common/options -I./../../../../common/options -I../../../../common/stream -I./../../../../common/stream -I../../../../gdk -I./../../../../gdk -DLIBUDF -g -O2 -c udf.c  -fPIC -DPIC -o .libs/lib_udf_la-udf.o
/bin/bash ../../../../libtool --tag=CC   --mode=link gcc -DLIBUDF  -g -O2  -module -avoid-version  -o lib_udf.la -rpath /usr/local/lib/monetdb5 lib_udf_la-hll.lo lib_udf_la-udf.lo  ../../../../monetdb5/tools/libmonetdb5.la ../../../../gdk/libbat.la 
libtool: link: gcc -shared  -fPIC -DPIC  .libs/lib_udf_la-hll.o .libs/lib_udf_la-udf.o   -Wl,-rpath -Wl,/home/mping/workspace/monetdb/MonetDB-11.13.5/monetdb5/tools/.libs -Wl,-rpath -Wl,/home/mping/workspace/monetdb/MonetDB-11.13.5/gdk/.libs ../../../../monetdb5/tools/.libs/libmonetdb5.so ../../../../gdk/.libs/libbat.so  -O2   -pthread -Wl,-soname -Wl,lib_udf.so -o .libs/lib_udf.so

【问题讨论】:

    标签: c


    【解决方案1】:

    当您在头文件中定义数组int const SHIFT_TABLE[1024] = {...} 时。然后你在同一个项目的 2 c 文件中引用头文件这就像在 2 c 文件中定义数组两次一样。这就是你的问题的原因。

    即使您使用 #ifndef,这也不会避免您的预处理将定义包含在第二个 C 文件中

    来自Preprocessor #ifndef

    标准标题可以按任何顺序包含;每个都可能包括在内 在给定范围内不止一次,没有任何不同的效果 只包含一次

    您可以检查在预处理代码中,您会发现数组被定义了两次,这是错误的。你可以用gcc -E生成你的预处理代码

    #ifndef 仅在您检查不同头文件而不是同一个头文件中的常量宏时才有效

    为避免该问题,您可以在c 文件之一中定义您的数组。而你在头文件中将数组定义为extern

    在其中一个 C 文件中

    int const SHIFT_TABLE[1024] = {...};
    

    在头文件中:

    extern int const SHIFT_TABLE[1024];
    

    【讨论】:

    • 编译步骤确实有效,但运行程序时出错。不幸的是,我无法获得有关该错误的更多详细信息,因为它是第三方应用程序。
    • 尝试提供一个小代码来重现您的问题以帮助您
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多