【问题标题】:C++ undefined reference to defined functionC++ 未定义对已定义函数的引用
【发布时间】:2011-05-07 00:53:41
【问题描述】:

我无法弄清楚为什么这不起作用。我将把我的所有三个文件都放好,可能有人可以告诉我为什么它会抛出这个错误。我正在使用g++编译程序。

程序:

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

using namespace std;

int main()
{
  char sentence[MAX_SENTENCE_LENGTH];
  char writeTo[] = "output.txt";
  int distanceTo,likePosition, length, numWords;
  cout << "ENTER A SENTENCE!   ";
  cin.getline(sentence, 299);
  length = strlen(sentence);
  numWords = wordCount(sentence, length);
  for(int x = 0; x < 3; ++x)
  {
    likePosition = likePos(numWords);
    distanceTo = lengthTo(sentence, likePosition, length);
    insertLike(sentence, distanceTo, length, writeTo);
  }
  return 0;  
}

函数文件:

void insertLike(const char sentence[],  const int lengthTo, const int length, char writeTo[])
{
  char part1[MAX_SENTENCE_LENGTH], part2[MAX_SENTENCE_LENGTH];
  char like[] = " like ";
  for(int y = 0; y < lengthTo; ++y)
    part1[y] = sentence[y];
  for(int z = lengthTo+1; z < length - lengthTo; ++z)
    part2[z] = sentence[z];
  strcat(part1, like);
  strcat(part1, part2);
  writeToFile(sentence, writeTo);
  return;
}

头文件:

void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]);

错误是:

undefined reference to 'insertLike(char const*, int, int, char const*)'
collect2: ld returned 1 exit status

【问题讨论】:

    标签: c++ g++ undefined-reference


    【解决方案1】:

    正如 Paul 所说,这可能是链接器投诉,而不是编译器错误。如果您仔细阅读构建输出/日志(可能需要在单独的 IDE 窗口中查看完整的详细信息),您可以确定问题是来自编译器(需要在代码中修复)还是来自链接器(并且需要将在 make/cmake/project 级别修复以包含缺少的库)。

    【讨论】:

      【解决方案2】:

      如果你包含一个依赖于另一个库的库,那么包含的顺序也很重要:

      g++ -o MyApp MyMain.o -lMyLib1 -lMyLib2
      

      在这种情况下,MyLib1 依赖于 MyLib2 是可以的。 但是,如果 reverse 为真,您将获得未定义的引用。

      【讨论】:

        【解决方案3】:

        虽然之前的海报涵盖了您的特定错误,但如果您不告诉编译器使用 C 链接,则在尝试使用 g++ 编译 C 代码时可能会出现“未定义引用”链接器错误。

        例如,您应该在 C 头文件中执行此操作:

        extern "C" {
        
        ...
        
        void myfunc(int param);
        
        ...
        
        }
        

        使“myfunc”在 C++ 程序中可用。

        如果您还想在 C 中使用它,请将 extern "C" {} 包装在 #ifdef __cplusplus 预处理器条件中,例如

        #ifdef __cplusplus
        extern "C" {
        #endif
        

        这样,extern 块在使用 C 编译器时将被“跳过”。

        【讨论】:

        • 链接器确实应该检查这种情况并告诉您定义了函数的未修改版本!
        • @karora 很高兴你添加了这个,但是这个问题只被标记为 c++ 所以我认为在 C 中使用相同代码的能力应该是一个额外的评论。
        • @leftaroundabout 也许这个问题也应该标记为 C,因为这个错误确实发生在两种语言之间的无人区。我的 C 代码工作得很好,直到我不得不从 C++ 程序中调用它,但是当我在此处进行推荐的更改时,它开始为 C++ 工作,但破坏了我的工作 C 程序,因此我的建议。
        【解决方案4】:

        insertLike的声明和定义不同

        在你的头文件中:

        void insertLike(const char sentence[], const int lengthTo, const int length, const char writeTo[]);

        在您的“函数文件”中:

        void insertLike(const char sentence[], const int lengthTo, const int length,char writeTo[]);

        C++ 允许函数重载,您可以在其中拥有多个同名的函数/方法,只要它们具有不同的参数。参数类型是函数签名的一部分。

        在这种情况下,以const char*为第四个参数的insertLike和以char *为第四个参数的insertLike不同的功能

        【讨论】:

        • 有时它只需要一组额外的眼球,伙计。 :) 我记得我学C的时候,我会用半天的时间沮丧地把头敲在键盘上,然后我的岳父会回来指着我的肩膀说,“你少了一个分号那里。” >.>
        • 嗯,从来没有岳父。可能是为什么我花了半天以上的时间沮丧地敲击键盘:-)
        • 有没有办法让机器帮我捕捉到这个错误?
        • @ulidtko 机器确实捕获了错误。问题是 OP 不明白机器在告诉他什么。我想编译器有可能识别出声明函数和定义函数之间的相似性并提出有用的建议(“你的意思是......?”)
        【解决方案5】:

        如果您使用 CMake,也可能发生这种情况。如果您创建了一个新类并且想要实例化它,那么在构造函数调用时您将收到此错误 - 即使标题和 cpp 文件是正确的 - 如果您没有相应地修改 CMakeLists.txt

        使用 CMake,每次创建新类时,在使用它之前,必须将 cpp 文件和任何其他可编译文件(如 Qt ui 文件)添加到 CMakeLists.txt,然后重新运行cmake . 存储CMakeLists.txt

        例如,在这个CMakeLists.txt 文件中:

        cmake_minimum_required(VERSION 2.8.11)
        
        project(yourProject)
        
        file(GLOB ImageFeatureDetector_SRC *.h *.cpp)
        
        ### Add your new files here ###
        add_executable(yourProject YourNewClass.h YourNewClass.cpp otherNewFile.ui})
        
        target_link_libraries(imagefeaturedetector ${SomeLibs})
        

        如果您使用命令file(GLOB yourProject_SRC *.h *.cpp),那么您只需要重新运行cmake .而不修改CMakeLists.txt

        【讨论】:

        • make rebuild_cache 是另一种强制重新配置的方法。此外,这就是为什么您不使用文件名 GLOBs 构建 CMakeLists 的原因。毕竟它们被称为 CMakeLists 是有原因的。
        【解决方案6】:

        您需要将所有源文件编译并链接在一起:

        g++ main.c function_file.c
        

        【讨论】:

        • 同在这里,试图在Debian机器上编译一些VS代码,才发现这个,谢谢你的回答!你甚至可以按照stackoverflow.com/questions/3202136/…g++ *.c
        • 我可以像上面那样(从 .C 文件编译)并成功,但是当我从 .O 目标文件编译(链接)时,它会失败,我必须另外修改一些声明才能实现工作。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-06-08
        • 2022-05-03
        • 1970-01-01
        • 2017-05-27
        • 1970-01-01
        相关资源
        最近更新 更多