对 main 的未定义引用 -collect2:ld 返回 1 退出状态

问题描述 投票:0回答:9

我正在尝试编译一个程序(称为 es3),但是,当我从终端写入时:

gcc es3.c -o es3

出现此消息:

/usr/lib/gcc/i686-linux-gnu/4.4.5/../../../../lib/crt1.o: In function `_start':
(.text+0x18): undefined reference to `main'
collect2: ld returned 1 exit status

我能做什么?

c gcc reference
9个回答
71
投票

这意味着

es3.c
没有定义
main
函数,并且您正在尝试用它创建一个可执行文件。可执行文件需要有一个入口点,因此链接器会抱怨。

要仅编译为目标文件,请使用

-c
选项:

gcc es3.c -c
gcc es3.o main.c -o es3

上面将

es3.c
编译为目标文件,然后编译一个包含
main.c
函数的文件
main
,链接器将
es3.o
main.o
合并为名为
es3
的可执行文件。


18
投票

也许您的

main
函数已被注释掉,因为例如预处理。 要了解预处理的作用,请尝试
gcc -C -E es3.c > es3.i
,然后使用编辑器查看生成的文件 es3.i(并在其中搜索
main
)。

首先,您应该始终(因为您是新手)使用

进行编译
  gcc -Wall -g -c es3.c
  gcc -Wall -g es3.o -o es3

-Wall
标志非常重要,您应该始终使用它。它告诉编译器向您提供(几乎)所有警告。并且您应该始终听取警告,即更正您的源代码文件
es3.C
,直到不再收到警告为止。

-g
标志也很重要,因为它要求
gcc
将调试信息放入目标文件和可执行文件中。然后您就可以使用调试器(如
gdb
)来调试您的程序。

要获取目标文件或可执行文件中的符号列表,您可以使用

nm

当然,我假设您使用 GNU/Linux 系统(如果您还没有使用 GNU/Linux,我邀请您使用它)。


15
投票

就我而言,这只是因为我没有保存源文件并试图编译一个空文件。


8
投票

可执行文件需要一个main函数。请参阅下面的 hello world 演示。

#include <stdio.h>
int main(void)
{
        printf("Hello world!\n");
        return 0;
}

如你所见,有一个主要功能。如果没有这个main函数,ld会报“undefined reference to main'”

检查我的结果:

$ cat es3.c
#include <stdio.h>
int main(void)
{
    printf("Hello world!\n");
    return 0;
}
$ gcc -Wall -g -c es3.c
$ gcc -Wall -g es3.o -o es3
~$ ./es3
Hello world! 

请使用

$ objdump -t es3.o
检查是否有主要符号。下面是我的结果。

$ objdump -t es3.o

es3.o:     file format elf32-i386

SYMBOL TABLE:
00000000 l    df *ABS*  00000000 es3.c
00000000 l    d  .text  00000000 .text
00000000 l    d  .data  00000000 .data
00000000 l    d  .bss   00000000 .bss
00000000 l    d  .debug_abbrev  00000000 .debug_abbrev
00000000 l    d  .debug_info    00000000 .debug_info
00000000 l    d  .debug_line    00000000 .debug_line
00000000 l    d  .rodata        00000000 .rodata
00000000 l    d  .debug_frame   00000000 .debug_frame
00000000 l    d  .debug_loc     00000000 .debug_loc
00000000 l    d  .debug_pubnames        00000000 .debug_pubnames
00000000 l    d  .debug_aranges 00000000 .debug_aranges
00000000 l    d  .debug_str     00000000 .debug_str
00000000 l    d  .note.GNU-stack        00000000 .note.GNU-stack
00000000 l    d  .comment       00000000 .comment
00000000 g     F .text  0000002b main
00000000         *UND*  00000000 puts

4
投票

到目前为止尚未提及的一种可能性是您可能没有编辑您认为正在编辑的文件。也就是说,您的编辑器可能有与您想象的不同的 cwd。

在您正在编译的文件上运行“more”,以仔细检查它是否确实包含您希望的内容。希望有帮助!


3
投票

就我的情况而言,我发现主函数声明的

void
丢失了。

我之前在 Windows 中使用 Visual Studio,这从来都不是问题,所以我想我现在也可以忽略它。


2
投票

您只需添加一个

main
函数即可解决此问题。 就像:

int main()
{
    return 0;
}

0
投票

就我而言,我使用的是 NS3,C++ 文件以

.cc
文件扩展名保存。我将文件保存为常用方式
.cpp

就这么简单,但我花了一段时间才认识到它。


0
投票

回复这个问题真的很晚了,但我遇到了这个问题,最终导致了 makefile 错误。

我忘了包括

all: $(MODULE_NAME).o
在我的 makefile 中。

如果您遇到同样的问题,请务必检查您的 make 文件。

© www.soinside.com 2019 - 2024. All rights reserved.