我如何理解这个编译器错误:“多重定义...”
我正在做我的考试作业。大约还有 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();
}
有人请帮助我或杀了我。我不想生活在一个可能出现这种错误的世界里。
对可能出什么问题有什么想法吗?
I'm working on my exam assignment. It's due in almost 6 hours. Suddenly my program won't compile anymore with this error message:
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
In this file:
#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();
}
Someone please help me or kill me. I don't want to live in a world where this sort of error is possible.
Any ideas to what might be wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
正如我在评论中提到的,问题在于
h_meta
和h_meta_len
的多个定义 - 因为它们是在 .h 文件中定义的,该文件包含在 more 中比一个翻译单元,或者由于 .c(带有变量的定义,直接或包含在包含的 .h 中)被包含在另一个 .c 中。包含防护可以避免编译错误,但不能避免链接错误。这让我想到了奇怪的错误消息:您在链接时收到这些消息。链接器对目标文件进行操作,其中包含 .c 文件中的代码及其包含的所有文件。因此,假设
h_meta
和friend 没有直接在两个.c 文件中定义,则链接器只能做这么多来为您提供有用的信息。在 VC 中,您只会收到一条消息,告诉您有多个定义和目标文件列表(而不是 .c)。因此,鉴于定义来自上述 .c 文件中包含的文件,因此定义没有实际的行号。我猜 GCC 只是默认到源代码的开头。
As I've mentioned in my comment, the problem is with multiple definitions of
h_meta
andh_meta_len
- be it due to them being defined in a .h file that's included in more than one translation unit, or due to .c (with the definition of the variables, either directly or in an included .h) being included in another .c. Include guards will save you from compilation errors, but not from link errors.And this brings me to the weird error messages: You get those at link time. The linker operates on object files, which contain code from a .c file and all the files it had included. So, assuming
h_meta
and friend are not defined directly in two .c files, there's only so much the linker can do to provide you useful information. In VC, you'd only get a message telling you that there are multiple definitions, and the list of object files (rather than .c).So, given the definitions come from files included in the mentioned .c files, there's no actual line number for the definitions. I guess GCC just defaults to the beginning of the source.
您的头文件
history.h
包含变量声明。您必须将此文件包含在多个源文件中。这会导致变量被声明多次。相反,您应该查看extern
关键字或重新考虑您的实现。Your header file
history.h
contains variable declarations. You must be including this file in multiple source files. This causes the variable to be declared multiple times. Instead you should either look into theextern
keyword or reconsider your implementation.就像其他人所说的那样,您不应该在标头中“定义”(隐式或显式分配空间)变量。
这个示例可能会有所帮助:
当然,您可能在 .c/.cpp 文件中定义的任何全局变量也是如此。
全局只能被精确地“定义”一次。
Like the others have said, you should not "define" (either implicitly or explicitly allocate space for) a variable in your headers.
This example might help:
The same, of course, goes for any globals you might define in your .c/.cpp files.
A global can only be "defined" exactly once.
C 程序中的每个对象(变量的存储空间)只能有一个定义(分配值的声明)。
您的头文件包含多个变量的定义,当这些变量包含在多个不同的翻译单元中时,会导致链接器抛出此错误。您的头文件至少包含在两个翻译单元中,一个用于 history.c,另一个用于 tomashell.c。
有关定义构成的更多信息请参见此处。
A program in C can have only one definition (declaration which assigns a value) for each object (storage space for a variable).
Your header file contains definitions for several variables, which when included in several different translation units results in the linker throwing this error. Your header file is included in at least two translation units, one for history.c, and another one for tomashell.c.
More information on what constitutes a definition here.
比较 safefork.c:11 和 History.c:4
看起来您的符号被定义了两次。
Compare safefork.c:11 and history.c:4
Looks like your symbol is being defined twice.