【问题标题】:Undefined reference to main - collect2: ld returned 1 exit status对 main 的未定义引用 - collect2:ld 返回 1 个退出状态
【发布时间】:2011-11-01 10:56:33
【问题描述】:

我正在尝试编译一个程序(称为 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

我能做什么?

【问题讨论】:

  • 发布导致此错误的代码可能是个好主意。
  • @BrandoSK:当我点击该链接时,我得到了 45 秒的倒计时。要么将代码作为问题的一部分发布,要么将其缩小为一个说明问题的小示例并发布。
  • 好的,我刚刚下载了你的源文件。 (1) 它被称为es3_f3.c,而不是es3.c。 (2) 它包含多个错误,例如第 18 行缺少分号。它不可能编译,这意味着您无法看到您报告的链接器错误。向我们展示您的真实代码。 (下载的源文件有73行,够短,直接贴在这里。)
  • 您显示的错误消息与我将命令gcc es3.c -o es3 与未定义main 函数的源文件一起使用时得到的错误消息非常相似。无论您真正编译的任何源文件都没有定义 main 函数。
  • 也许你搞砸了你的编译器安装,或者你想要一些cross compiler。还要检查您的$PATH

标签: c gcc reference


【解决方案1】:

这意味着es3.c 没有定义main 函数,而您正试图从中创建可执行文件。可执行文件需要有一个入口点,因此链接器会抱怨。

要仅编译为目标文件,请使用-c 选项:

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

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

【讨论】:

  • 问题是我把main函数放在我的程序里面了..我不明白为什么它说没有main函数...:/
【解决方案2】:

也许您的 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,我邀请您使用它)。

【讨论】:

  • 是的,我正在使用 Ubuntu!我去试试你说的谢谢..!
【解决方案3】:

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

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

如您所见,有一个 main 函数。如果没有这个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

【讨论】:

  • 感谢您的回答,但我的程序中有 main 函数 :( 不明白为什么编译器不读取它 :(
  • 我已经在我的linux上验证过了,请检查一下。
  • 我相信你并没有真正的主;它被隐藏,被预处理器跳过,内部或静态...尝试indent您的文件,它对您来说更具可读性...
  • @Basile Starynkevitch:我有一个主要的。但我认为 BrandoSK 没有主要功能。你怎么看?
  • 是的,我正在和原始发帖人 BrandoSK 交谈。当编译器说不main时,他应该相信编译器!!
【解决方案4】:

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

【讨论】:

  • 在我的情况下,我早先从一个目录打开文件到 gedit,然后将其移动到另一个目录并尝试从我最近移动的新目录编译。但是文件是空的,因为它已经打开了。
【解决方案5】:

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

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

【讨论】:

    【解决方案6】:

    您只需添加一个main 函数即可解决此问题。 就像:

    int main()
    {
        return 0;
    }
    

    【讨论】:

    • O.P. 有一个main 函数。
    【解决方案7】:

    在我的情况下,我发现主函数声明的 void 丢失了。

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

    【讨论】:

      猜你喜欢
      • 2015-06-13
      • 1970-01-01
      • 2012-08-02
      • 2012-02-18
      • 1970-01-01
      • 2020-10-04
      • 1970-01-01
      • 2011-08-26
      • 1970-01-01
      相关资源
      最近更新 更多