多个定义...链接器错误

maz*_*zix 43 c linker linker-errors

我定义了一个特殊文件: config.h

我的项目还有文件:

t.c, t.h
pp.c, pp.h
b.c b.h
l.cpp
Run Code Online (Sandbox Code Playgroud)

和#includes:

在tc:

    #include "t.h"
    #include "b.h"
    #include "pp.h"
    #include "config.h"
Run Code Online (Sandbox Code Playgroud)

在bc:

    #include "b.h"
    #include "pp.h"
Run Code Online (Sandbox Code Playgroud)

在pp.c:

    #include "pp.h"
    #include "config.h"
Run Code Online (Sandbox Code Playgroud)

在l.cpp中:

    #include "pp.h"
    #include "t.h"
    #include "config.h"
Run Code Online (Sandbox Code Playgroud)

我的*.h文件中没有include指令,只在*.c文件中.我在config.h中定义了这个:

const char *names[i] =
        {
            "brian", "stefan", "steve"
        };
Run Code Online (Sandbox Code Playgroud)

并在l.cpp,tc,pp.c中需要该数组但是我收到此错误:

pp.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
t.o:(.data+0x0): multiple definition of `names'
l.o:(.data+0x0): first defined here
collect2: ld returned 1 exit status
make: *** [link] Error 1
Run Code Online (Sandbox Code Playgroud)

*.h在我的项目中使用的每个文件中都包含了警卫.任何帮助解决这个问题

Yu *_*Hao 102

不要在标题中定义变量.将声明放在其中一个.c文件的标头和定义中.

在config.h中

extern const char *names[];
Run Code Online (Sandbox Code Playgroud)

在某些.c文件中:

const char *names[] =
    {
        "brian", "stefan", "steve"
    };
Run Code Online (Sandbox Code Playgroud)

如果在头文件中放置全局变量的定义,那么此定义将转到包含此头的每个.c文件,并且您将获得多个定义错误,因为varible可能被多次声明但是只能定义一次.

  • 所以它不会这样做.仅使用*.h文件来引用信息.您必须记住,"include"表示它包含该文件中的所有*.h信息,因此您将使用*.h将该信息(不仅仅是引用)复制到每个文件中.这可能会使链接器混淆,并且确实如此. (3认同)
  • @mazix不,全局变量的**定义**应该转到.c文件,并将**声明**放在标题中.请记住,您可以多次声明变量,但只能定义一次. (2认同)

小智 26

公共函数的声明放在头文件中,是的,但定义在标题中也绝对有效!如果要在实用程序函数的标题中定义事物,而不想在每个c文件中再次定义,则可以将定义声明为静态(整个程序只允许1个副本).IE定义枚举和静态函数以将枚举转换为字符串.然后,您不必为包含标头的每个.c文件重写enum到字符串转换器.:)

  • 这不是对静态功能的准确描述。“您可以将定义声明为静态(整个程序只允许 1 个副本)”不!static 使定义范围限定为该编译单元。所以它给你一份_per_ _compile_ _unit_。所以如果你有一些大的字符串列表,你的程序最终会得到这个列表的许多重复副本……每个 c 文件一个。如果您稍后去调试它,这对于静态函数来说更糟,因为不再有单个函数可以放置断点,而是在生成的链接程序中该函数的许多副本。 (4认同)
  • 实际上,我发现此答案比顶部答案要方便得多。仅具有一个标头来存储所有全局变量(例如,而不是具有.h和.cpp文件)会更方便且更有吸引力。谢谢。 (2认同)