C++ undefined reference to defined function

139,005

Solution 1

The declaration and definition of insertLike are different

In your header file:

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

In your 'function file':

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

C++ allows function overloading, where you can have multiple functions/methods with the same name, as long as they have different arguments. The argument types are part of the function's signature.

In this case, insertLike which takes const char* as its fourth parameter and insertLike which takes char * as its fourth parameter are different functions.

Solution 2

Though previous posters covered your particular error, you can get 'Undefined reference' linker errors when attempting to compile C code with g++, if you don't tell the compiler to use C linkage.

For example you should do this in your C header files:

extern "C" {

...

void myfunc(int param);

...

}

To make 'myfunc' available in C++ programs.

If you still also want to use this from C, wrap the extern "C" { and } in #ifdef __cplusplus preprocessor conditionals, like

#ifdef __cplusplus
extern "C" {
#endif

This way, the extern block will just be “skipped” when using a C compiler.

Solution 3

You need to compile and link all your source files together:

g++ main.c function_file.c

Solution 4

This could also happen if you are using CMake. If you have created a new class and you want to instantiate it, at the constructor call you will receive this error -even when the header and the cpp files are correct- if you have not modified CMakeLists.txt accordingly.

With CMake, every time you create a new class, before using it the header, the cpp files and any other compilable files (like Qt ui files) must be added to CMakeLists.txt and then re-run cmake . where CMakeLists.txt is stored.

For example, in this CMakeLists.txt file:

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})

If you are using the command file(GLOB yourProject_SRC *.h *.cpp) then you just need to re-run cmake . without modifying CMakeLists.txt.

Solution 5

If you are including a library which depends on another library, then the order of inclusion is also important:

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

In this case, it is okay if MyLib1 depends on MyLib2. However, if there reverse is true, you will get undefined references.

Share:
139,005
Mashew
Author by

Mashew

Hello, I am a freshman comp sci student at Missouri S&T. Please answer my questions, I promise you aren't doing my homework. :3

Updated on March 30, 2020

Comments

  • Mashew
    Mashew about 4 years

    I cannot figure out why this is not working. I will put up all three of my files and possibly someone can tell me why it is throwing this error. I am using g++ to compile the program.

    Program:

    #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;  
    }
    

    Function file:

    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;
    }
    

    Header file:

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

    The error exactly is:

    undefined reference to 'insertLike(char const*, int, int, char const*)'
    collect2: ld returned 1 exit status
    
  • Mud
    Mud over 13 years
    Sometimes it just takes an extra set of eyeballs, man. :) I remember when I was learning C, and I'd spend half a day banging my head on the keyboard in frustration, then my father-in-law would come home and point over my shoulder, "You're missing a semicolon there." >.>
  • m-ric
    m-ric almost 10 years
    Well, never had a father-in-law. Probably why I spent way more than half a day banging my head on the keyboard in frustration :-)
  • mehov
    mehov over 8 years
    Same here, was trying to compile some VS code on a Debian machine and just found this, thanks for the answer! You can even do g++ *.c, as per stackoverflow.com/questions/3202136/…
  • ulidtko
    ulidtko over 7 years
    make rebuild_cache is another way to force the reconfiguration. Also, that's why you don't construct your CMakeLists out of filename GLOBs. There's a reason they're called CMakeLists after all.
  • ulidtko
    ulidtko over 7 years
    Is there any way to ask the machine to catch this error for me?
  • Mud
    Mud over 7 years
    @ulidtko The machine did catch the error. The problem is the OP didn't understand what the machine was telling him. I guess it would be possible for the compiler to recognize the similarity between the declared function and defined function and make a helpful suggestion ("Did you mean ...?")
  • jtbr
    jtbr about 7 years
    The linker really should check for this case and tell you that there is an unmangled version of the function defined!
  • leftaroundabout
    leftaroundabout over 6 years
    @karora it's nice that you added this, however the question is only tagged c++ so I think the ability to use the same code also in C should be more of an extra remark.
  • karora
    karora over 6 years
    @leftaroundabout perhaps the question should also be tagged C, because this error really happens in that no-mans land between the two languages. My C code was working just fine until I had to call it from a C++ program, but when I made the change recommended here it started working for C++, but broke my working C program, hence my suggestion.
  • Yan King Yin
    Yan King Yin about 4 years
    I can do it as above (compile from .C files) and succeed, but when I compile (link) from .O object files, it fails and I have to additionally modify some declarations to make it work.