C 我如何理解此编译器错误:“quot;“对……的多重定义”;

C 我如何理解此编译器错误:“quot;“对……的多重定义”;,c,linux,unix,gcc,C,Linux,Unix,Gcc,我正在做我的考试作业。大约6小时后就要交了。突然,我的程序将不再编译,并显示以下错误消息: gcc -g -D DEBUG -c -o obj/stringops.o src/stringops.c gcc -g -D DEBUG -c -o obj/arrayops.o src/arrayops.c gcc -g -D DEBUG -c -o obj/fileops.o src/fileops.c gcc -g -D DEBUG -c -o obj/builtins.o src/builtin

我正在做我的考试作业。大约6小时后就要交了。突然,我的程序将不再编译,并显示以下错误消息:

gcc -g -D DEBUG -c -o obj/stringops.o src/stringops.c gcc -g -D DEBUG -c -o obj/arrayops.o src/arrayops.c gcc -g -D DEBUG -c -o obj/fileops.o src/fileops.c gcc -g -D DEBUG -c -o obj/builtins.o src/builtins/*.c gcc -g -D DEBUG -c -o obj/tomashell.o src/tomashell.c gcc -g -D DEBUG -o bin/tomashell \ obj/stringops.o obj/arrayops.o obj/fileops.o obj/builtins.o \ obj/tomashell.o obj/tomashell.o: In function `n_processes': /root/sc/tomashell/src/safefork.c:11: multiple definition of `h_meta' obj/builtins.o:/root/sc/tomashell/src/builtins/history.c:4: first defined here obj/tomashell.o: In function `n_processes': /root/sc/tomashell/src/safefork.c:11: multiple definition of `h_meta_len' obj/builtins.o:/root/sc/tomashell/src/builtins/history.c:4: first defined here collect2: ld returned 1 exit status make: *** [bin/tomashell] Error 1 gcc-g-D DEBUG-c-o obj/stringops.o src/stringops.c gcc-g-D DEBUG-c-o obj/arrayops.o src/arrayops.c gcc-g-D DEBUG-c-o obj/fileops.o src/fileops.c gcc-g-D DEBUG-c-o obj/builtins.o src/builtins/*.c gcc-g-D DEBUG-c-o obj/tomashell.o src/tomashell.c gcc-g-D调试-o bin/tomashell\ obj/stringops.o obj/arrayops.o obj/fileops.o obj/builtins.o\ obj/tomashell.o obj/tomashell.o:在函数'n_processs'中: /root/sc/tomashell/src/safefork.c:11:h_meta的多重定义 obj/builtins.o:/root/sc/tomashell/src/builtins/history.c:4:首先在这里定义 obj/tomashell.o:在函数'n_processs'中: /root/sc/tomashell/src/safefork.c:11:h_meta_len的多重定义 obj/builtins.o:/root/sc/tomashell/src/builtins/history.c:4:首先在这里定义 collect2:ld返回了1个退出状态 make:**[bin/tomashell]错误1 在此文件中:

#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/errno.h>

extern int errno;

#define MAX_PROCESSES 6

static int n_processes(void)
{ // <- THIS IS LINE 11
    return system("exit `ps | wc -l`")/256;
}


pid_t safefork(void)
{
  static int n_initial = -1;

  if (n_initial == -1)
    n_initial = n_processes();
  else if (n_processes() >= n_initial+MAX_PROCESSES) {
    sleep(2);
    errno = EAGAIN;  return (pid_t)-1;
  }

  return fork();
}
#包括
#包括
#包括
#包括
外部内部错误;
#定义MAX_流程6
静态int n_进程(void)
{/=n_初始+MAX_过程){
睡眠(2);
errno=EAGAIN;返回(pid_t)-1;
}
返回叉();
}
谁来帮帮我,或者杀了我。我不想生活在一个有可能犯这种错误的世界里

对可能出现的问题有什么看法



比较safefork.c:11和history.c:4


看起来您的符号被定义了两次。

头文件
history.h
包含变量声明。您必须将此文件包含在多个源文件中。这会导致多次声明变量。相反,您应该查看
extern
关键字,或者重新考虑您的实现。

C语言中的程序对于每个对象(变量的存储空间)只能有一个定义(分配值的声明)

头文件包含多个变量的定义,当包含在多个不同的转换单元中时,链接器会抛出此错误。您的头文件至少包含在两个翻译单元中,一个用于history.c,另一个用于tomashell.c


有关定义的更多信息。

就像其他人所说的,您不应该在标题中“定义”(隐式或显式地为变量分配空间)

此示例可能有助于:

#ifndef HISTORY
#define HISTORY
...

/* Bad!  Don't actually DEFINE (allocate space for) variables in a header!
 * h_metablock* h_meta = NULL;
 * int h_meta_len = 0;
 */

/* Better: declare "extern", then define in exactly ONE module (e.g. "main.c") */
extern h_metablock* h_meta;
extern int h_meta_len;
...
当然,在.c/.cpp文件中定义的任何全局变量也是如此


一个全局只能“定义”一次。

正如我在评论中提到的,问题在于
h_meta
h_meta_len
的多个定义——可能是因为它们被定义在一个包含在多个翻译单元中的.h文件中,或者是由于.c(使用变量的定义,无论是直接的还是包含在Include.h中)包含在另一个.c.Include卫士中,都可以避免编译错误,但不会避免链接错误

这让我想到了奇怪的错误消息:你在链接时得到了这些消息。链接器对对象文件进行操作,这些文件包含.c文件及其包含的所有文件中的代码。因此,假设
h_meta
和friend没有直接在两个.c文件中定义,那么链接器可以为你提供的有用信息就那么多了在VC中,您只会收到一条消息,告诉您有多个定义和对象文件列表(而不是.c)


因此,鉴于定义来自上述.c文件中包含的文件,因此定义没有实际的行号。我猜GCC只是默认为源代码的开头。

您可以发布history.c文件吗?(第4行)我更改了标题,这不是很有建设性。另外,你真的读过这条消息吗?看起来很清楚。每个翻译单元都有包含守卫。如果几个.c文件包含相同的.h文件,并且该.h文件包含一个
int h_meta
,那么你应该有多个
h_meta
的定义。你应该在一个.cf中定义ile和.h文件中的一个
extern int h_meta
。您包含了一个C文件?停止它。您可能会发现,您在每个文件中都包含了相同的内容。safefork.C中的第11行和history.C中的第4行都是
{
。您完全正确。没有调试信息,gcc(实际上是从gcc调用的ld)会吐出
文件名(.bss+0xoffset)
。使用debuginfo,它试图将bss的偏移量转换为一些源代码行,结果打印出一行毫无意义的代码。@ninjalj,我很高兴听到我的留言(总是想用那个词…)是正确的。我几乎没有使用gcc,而使用VS,你甚至不会得到那么多。