• 从链接器的角度详细分析g++报错: (.text+0x24): undefined reference to `main'


    /usr/bin/ld: /usr/lib/gcc/x86_64-linux-gnu/9/../../../x86_64-linux-gnu/Scrt1.o: in function `_start':

    (.text+0x24): undefined reference to `main'

    collect2: error: ld returned 1 exit status

     

     在使用g++编译链接两个C++源文件main.cpp以及VecAdd.cpp时出现了以上编译报错。main.cpp中引用了VecAdd.cpp中定义的函数vecAdd来实现两个向量的加法。我们先说原因,再来分析一下g++为什么会报这样的错误。出现这个error的根本原因是错误地将g++命令行指令

    linux> g++ -o main main.cpp VecAdd.cpp 

    写成了

    linux> g++ -o main.cpp VecAdd.cpp 

    这样,g++会认为我们想要对VecAdd.cpp进行编译,得到一个名为main.cpp的可执行文件。而违背了我们的本意:将main.cpp与VecAdd.cpp编译并链接,得到可执行文件main. 在实验下,以上错误的指令不仅达不成我们的目的,还会将我们的C++源文件main.cpp给吃掉,很傻:

    再从链接器的角度审视一下这个错误:第一行的目录/usr/bin/ld是链接器的路径,第二行的(.text+0x24)表示目标文件出现错误的地方,也就是VecAdd.cpp对应的ELF格式的目标文件.text这一节(代码段)中地址偏移为0x24的地方。这里的undefined reference to main是什么意思? 一开始作者以为是对“main”这个符号的引用没有被定义,后来发现不是这样。做了实验后,发现真正的原因是:“在VecAdd.cpp中没有定义main函数”。我们编写了一个test.cpp.其中只有一条变量定义语句:

    //test.cpp
    int a = 5;

    使用指令

    linux> g++ -o test test.cpp

    来将test.cpp编译成可执行文件,发现链接器报了同样的错误:

     于是,问题得到了解答:g++ 的 -o 选项是将源代码编译成可执行文件,而C++源程序的程序入口是main函数,在最初的例子中:

    linux> g++ -o main.cpp VecAdd.cpp 

    由于错误输入,这条指令这是将VecAdd.cpp编译成名为main.cpp的可执行文件,而VecAdd.cpp中实现的是向量加法函数vecAdd,该源文件并没有主函数main(),于是就出现了"undefined reference to main"的链接器报错。

    可以通过使用IDE、编写shell脚本、使用cmake工具等更安全的工具,从而减少这样的失误带来的问题。

  • 相关阅读:
    陈胡:Apache SeaTunnel实现 非CDC数据抽取实践
    好心情平台:30分钟就可改善抑郁情绪的运动处方
    Three.js 这样写就有阴影效果啦
    Axure RP--快捷键大全(常用快捷键)
    Spring入门须知
    【Java】遨游在多线程的知识体系中(一)
    C++ - 完美语义(右值引用的中篇) - lambda表达式
    智能疾病查询接口
    div+css网页html成品学生作业包含10个html页面——动漫主题海贼王
    EMC VNX支持数据文件说明
  • 原文地址:https://www.cnblogs.com/pkuqcy/p/17760766.html