我正在完成考试作业。它将在近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
在此文件中:
#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();
}
有人请帮助我或杀了我。我不想生活在可能出现这种错误的世界。
对可能出错的任何想法?
答案 0 :(得分:3)
正如我在评论中提到的,问题在于h_meta
和h_meta_len
的多个定义 - 是因为它们是在.h文件中定义的,该文件包含在多个翻译中单位,或由于.c(变量的定义,直接或包含在.h中)包含在另一个.c中。包含防护可以避免编译错误,但不会导致链接错误。
这让我看到了奇怪的错误消息:您可以在链接时间获得这些消息。链接器对目标文件进行操作,目标文件包含.c文件中的代码及其包含的所有文件。因此,假设h_meta
和朋友没有直接在两个.c文件中定义,那么链接器只能为您提供有用的信息。在VC中,您只会收到一条消息,告诉您有多个定义和目标文件列表(而不是.c)。
因此,鉴于定义来自上述.c文件中包含的文件,定义中没有实际的行号。我猜GCC只是默认为源头的开头。
答案 1 :(得分:2)
您的头文件history.h
包含变量声明。您必须将此文件包含在多个源文件中。这会导致变量多次声明。相反,您应该查看extern
关键字或重新考虑您的实施。
答案 2 :(得分:2)
与其他人所说的一样,你不应该在标题中“定义”(隐式或显式地为空间分配空间)。
此示例可能有所帮助:
#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文件中定义的任何全局变量。
全局只能完全“定义”一次。
答案 3 :(得分:1)
C中的程序只能为每个对象(变量的存储空间)提供一个定义(为其分配值的声明)。
您的头文件包含多个变量的定义,当包含在多个不同的转换单元中时,会导致链接器抛出此错误。您的标题文件至少包含两个翻译单元,一个用于 history.c ,另一个用于 tomashell.c 。
有关定义here的内容的更多信息。
答案 4 :(得分:0)
比较safefork.c:11和history.c:4
看起来你的符号被定义了两次。