3

我目前正在开发我的第一个“严肃”C 项目,一个 16 位 vm。当我将一个大源文件中的文件拆分为多个源文件时,链接器(无论是通过 clang、gcc、cc 还是 ld 调用)都会显示错误:

ld: duplicate symbol _registers in register.o and main.o for inferred 
    architecture x86_64

registers主文件中没有任何地方的声明。如果有帮助,它是一个uint16_t数组。我在 Mac OS 10.7.3 上使用内置编译器(不是 GNU gcc)。有什么帮助吗?

4

1 回答 1

13

听起来您已经在标头中定义了一个变量,然后将其包含在两个不同的源文件中。

首先,您必须了解声明某事物(声明它存在于某处)和定义它(实际上是创建它)之间的区别。假设您有以下文件:

header.h:
    void printIt(void);           // a declaration.
    int xyzzy;                    // a definition.

main.c:
    #include "header.h"
    int main (void) {
        xyzzy = 42;
        printIt();
        return 0;
    }

other.c:
    #include <stdio.h>
    #include "header.h"
    void printIt (void) {         // a definition.
        printf ("%d\n", xyzzy);
    }

当您编译 C 程序时,每个生成的目标文件都会调用一个变量,xyzzy因为您通过包含头文件有效地在两者中定义了它。这意味着当链接器尝试组合这两个对象时,会遇到多个定义的问题。

解决办法是在头文件中声明东西,在C文件中定义,比如:

header.h:
    void printIt(void);           // a declaration.
    extern int xyzzy;             // a declaration.

main.c:
    #include "header.h"
    int xyzzy;                    // a definition.
    int main (void) {
        xyzzy = 42;
        printIt();
        return 0;
    }

other.c:
    #include <stdio.h>
    #include "header.h"
    void printIt (void) {         // a definition.
        printf ("%d\n", xyzzy);
    }

这样,other.c知道xyzzy存在,但只main.c创造它。

于 2013-08-13T08:26:14.277 回答