为啥我得到“未定义的 main 引用”

Posted

技术标签:

【中文标题】为啥我得到“未定义的 main 引用”【英文标题】:Why am I getting "undefined reference to main"为什么我得到“未定义的 main 引用” 【发布时间】:2018-02-23 02:43:33 【问题描述】:

我是一个编程新手,有一个非常基本的问题,可以在其他线程中回答,但我认为它们太先进了,我无法理解。到目前为止,我实际上已经在这个网站上找到了很多答案,但这是迫使我创建一个帐户并询问的第一个问题。 无论如何,我正在 linux mint 18.3 上运行一个非常基本的示例程序。现在我已经看到这个确切的代码在我相信的 Windows 8 机器上工作,所以我想知道这是否是问题所在。我创建了一个类,当我插入我的对象然后构建并运行时,我得到:

/usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o||在函数_start':| (.text+0x20)||undefined reference tomain'|

这是完整的代码:

#include <iostream>
#include "Gladius.h"
using namespace std;

int main()

    Gladius io;
    return 0;

这是非常基本的。这是.h

#ifndef GLADIUS_H
#define GLADIUS_H


class Gladius

    public:
        Gladius();

;

#endif // GLADIUS_H

以及类的 .cpp。

#include "Gladius.h"
#include <iostream>

using namespace std;
Gladius::Gladius()

    cout << "The Gladius is a short sword" << endl;

我知道这看起来非常简单,但我只是在学习编码,我一直在寻找解释为什么这不起作用但我看到它在另一台电脑上完全正常工作。无论如何,任何解释都将不胜感激。

这是我在命令行中找到的如果这回答了您关于 cmd 中的内容的问题。

g++ -Wall -fexceptions -g -std=c++11 -Wall -I -c /home/gator/Documents/Spartan1/Gladius.cpp -o obj/Debug/Gladius.o /usr/lib/gcc/x86_64-linux-gnu/5/../../../x86_64-linux-gnu/crt1.o:在函数_start': (.text+0x20): undefined reference tomain' collect2: error: ld 返回 1 个退出状态

【问题讨论】:

这段代码没有问题。我宁愿在编译器/IDE 设置中寻求不一致。你以前有过这种情况吗?您到底在使用哪个编译器(及其版本)?编辑:或者您可能没有使用main 实现链接文件。 makefile\build 步骤有问题。应该建立步骤,请 我正在使用来自 code::blocks 的 GNU GCC 编译器,我刚刚得到了我相信的最新版本。 【参考方案1】:

您的编译器的命令行包含-I -c 序列。

这个-I 选项“吞噬”了您的-c 选项。 -I 需要一个附加参数,即包含目录名称。您未能提供该参数,这就是为什么-I 假定它后面的-c 是目录名称。所以-I 消耗了-c

编译器永远不会看到-c。如果没有-c,它假定您要编译并链接您的程序。由于Gladius.cpp 中没有main,因此在链接阶段会出现错误。

这里有一个相同问题的简单演示:http://coliru.stacked-crooked.com/a/8a37cd3e90a443e2

你需要弄清楚为什么你的命令行中有一个孤立的-I

【讨论】:

【参考方案2】:

如果您使用如下命令行编译此代码:

g++ -Wall -Wextra -Werror -O gladius.cpp -o output.exe

然后确保包含所有包含程序所需代码的 .cpp 文件(不是 .h 文件)。

g++ -Wall -Wextra -Werror -O gladius.cpp main.cpp -o output.exe

我一直向初学者解释这一点,因为每个 .cpp 都是套件中的一袋乐高积木。您需要盒子随附的所有袋子来构建套件。如果您省略了 main.cpp(或包含 main 的文件),那么您将收到当前遇到的链接器错误。

【讨论】:

谢谢大家的回答哇这真的向我展示了我真的是一个新手。我正在使用代码::时钟。我如何准确地查看我的编译器命令。 顺便说一句,我真的很感激这些反馈,尽管它有点过头了,但我有信心我能弄明白。 1 如何准确地查看或更改命令行中的代码。我是否必须从 linux 的终端执行此操作,还是可以直接从 code::blocks 执行此操作 我相信你是正确的,但是如果我构建gladius.cpp 或main.cpp,它们都不会出现在构建日志中。我只是无法弄清楚为什么他们不会链接。我应该手动更改命令吗?我很紧张这样做,因为它说只有当你真的知道你在做什么时才这样做,因为你可以破坏你的编译器。除非我知道我正在改变正确的东西,否则我绝对没有信心改变它【参考方案3】:

了解编译器选项(gcc/g++编译器):

-c : 编译汇编,但不链接 -o file : 将输出放入file

所以当你运行时

g++ filename.cpp -o executable_name

,你生成一个可以执行的应用程序。

问题是当您尝试编译“Gladius.cpp”并且编译器尝试搜索 main() 定义时,您正在编译、组装和链接。

所以在你的情况下,编译步骤是:

首先编译“Gladius.cpp”并生成目标文件“Gladius.o”:

g++ -Wall -fexceptions -g -std=c++11 -c Gladius.cpp

接下来编译“main.cpp”并生成目标文件“main.o”:

g++ -Wall -fexceptions -g -std=c++11 -c main.cpp

通过链接“main.o”和“Gladius.o”生成可执行文件

 g++ -Wall -fexceptions -g -std=c++11 -o main main.o Gladius.o

现在你可以运行“main”了:

./main

【讨论】:

@AnT,是的 -c 选项被使用,但在编译时也试图链接 crt1.o ,所以编译器会混淆并且 -c 选项被忽略。 并非如此。编译器不会“感到困惑”。问题出在孤立的-I 开关上。【参考方案4】:

您使用什么命令来编译、链接然后执行?它应该看起来像

$ g++ main.cppgladius.cpp -odemo

$ ./demo

【讨论】:

好吧,我认为您不应该在答案中添加问题。他的问题下方有评论部分。 对不起,我意识到我对编程有多么陌生。我真的不知道如何查看我正在使用什么命令来编译。我正在使用的程序是 code::blocks【参考方案5】:

检查你的命令行链接步骤。你可能忘记了以 main 作为输入的文件,或者你忘记了 -o 之后的输出文件名(并且结果中的 main.o 被屏蔽了)

【讨论】:

【参考方案6】:

我自己也遇到过这种问题,虽然它可能不是传统的“正确”解决方案,但我只是将“.c”文件重命名为“.cpp”,然后一切正常。

毕竟,我使用 c++ 编译器(由库推荐)同时编译 c 和 c++,并且 c 代码已经具有正确的 c++ #extern 标志(有关更多信息,请参阅 here)。

也相关:

C++ Error: undefined reference to `main' Including C Code in C++ Why do you need an explicit `-lm` compiler option Compilation on Linux - In function '_start': (.text+0x20): undefined reference to 'main'

【讨论】:

以上是关于为啥我得到“未定义的 main 引用”的主要内容,如果未能解决你的问题,请参考以下文章

为啥我得到:“未定义的对 `glfwInit' 的引用”?

为啥我得到“未定义不是对象(评估 PropTypes.shape)”?

为啥我从 html doc 得到函数未定义错误?

为啥我总是在这个 ajax 帖子到 php 时得到未定义的响应?

为啥我得到一个未定义的 pthread_create 引用? [复制]

为啥我在这个 SASS 文件中得到一个未定义的 Foundation 变量错误?