【问题标题】:Duplicate symbols while linking链接时重复符号
【发布时间】:2013-12-06 18:42:13
【问题描述】:

我正在尝试使用此 makefile 编译我的程序,但链接器让我大惊小怪,说有重复的符号。我试过玩这个makefile,但运气不好。我的程序只有三个文件,pdp429.c、instructions.c 和 global.h。感谢任何帮助!

这是错误,(有 46 个“重复符号”错误) “重复符号 _MASK_IN 在: pdp429.o 说明.o ld:架构 x86_64 的 46 个重复符号 collect2: ld 返回 1 个退出状态 make: *** [pdp429] 错误 1"

CFLAGS = -O0 -pg -ggdb3 -Wall

all:    pdp429

pdp429: pdp429.o instructions.o
    gcc $(CFLAGS) pdp429.o instructions.o -o pdp429

pdp429.o: pdp429.c global.h
    gcc $(CFLAGS) pdp429.c -c

instructions.o: instructions.c global.h
    gcc $(CFLAGS) instructions.c -c

clean:
    rm -f *.o pdp429

【问题讨论】:

  • 那么实际错误是什么,这些符号实际定义在哪里?它可能根本与您的 makefile 无关
  • ld:架构 x86_64 collect2 的 46 个重复符号:ld 返回 1 个退出状态 make:*** [pdp429] 错误 1
  • 根据您的编辑,其中一个重复的符号被命名为_MASK_IN 对吗?现在 - 您的 3 个文件中的哪一个是 _MASK_IN 定义的,以及它是如何定义的。注意:向我们展示您在其中定义 _MASK_IN 的文件中的整行。
  • 消息很大。这是说我的目标文件中有重复的符号。我在想这是因为我在我的两个 c 文件中都包含 global.h 但我在 global.h 上设置了防护措施,例如“#ifndef GLOBAL_H...”
  • _MASKI_IN 在 global.h 中定义如下 "short MASK_IN = 0x0001;"

标签: c makefile


【解决方案1】:

您没有提供一些关键信息,但直接猜测您设法在 globals.h 头文件中定义了一些具有外部链接的实体(即变量或函数)。由于您的 globals.h 可能包含在您的两个 *.c 文件中,因此您最终会遇到多个定义错误。

从错误消息来看,MASK_IN 是明显的候选者。什么是MASK_IN,它是如何以及在哪里定义的?

编辑:所以,给你。您的MASK_INglobals.h 中定义为short MASK_IN = 0x0001;。这肯定会导致多重定义错误。看起来您实际上试图定义一个命名常量。如果是这样,在 C 语言中通常会使用 #define 来定义清单常量,即做

#define MASK_IN 0x0001

但如果你真的想使用命名对象,那么对于标量类型,最好的方法是这样做

static const short MASK_IN = 0x0001;

在头文件中。

如果您的 MASK_IN 旨在成为全局变量(不是常量),那么您唯一的选择是使用

extern short MASK_IN;

在头文件中和

short MASK_IN = 0x0001;

在一个(也是唯一一个).c 文件中。

【讨论】:

  • 啊好吧,有道理我会去试试。非常感谢!
  • 我添加了“静态”,它解决了这个问题。我仍然是一个 C 菜鸟,所以谢谢你今天教我一些东西!
  • @Sean:如果它打算成为一个清单常量,请将其设为static const。但在 C 语言中,使用#defineenum,而不是static const 通常会更好。
  • @Sean:static 对头文件中声明的变量的影响是使其成为文件本地的。这意味着包含该标头的每个文件都有自己的变量副本。
  • @ZanLynx 好的,我明白了。我回去用#define替换了static
【解决方案2】:

你还没有提供人们要求的信息,但我要冒昧地说:

  1. 您在global.h 中定义了_MASK_IN
  2. 您已将global.h 包含在多个源文件中。

这会导致符号被多重定义。您应该在标题中使用extern short _MASK_IN;,并在源文件中使用short _MASK_IN = 0x0001; 实际定义它。或者更好的是,假设它是常量,只需在头文件中#define 即可。

#ifndef 保护你的评论说你使用没有帮助,因为从一个源文件到下一个,这些保护被清除。 #define 仅在任何时间点正在编译的源代码中有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-10
    • 2010-12-17
    • 1970-01-01
    相关资源
    最近更新 更多