C++ undefined reference to defined function
Asked Answered
T

6

45

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
Tackling answered 9/11, 2010 at 4:8 Comment(0)
H
31

The declaration and definition of insertLike have different writeTo parameters.

In your header file, you have:

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

while 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.

Hames answered 9/11, 2010 at 4:13 Comment(5)
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." >.>Hames
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 :-)Interphase
Is there any way to ask the machine to catch this error for me?Denysedenzil
@Denysedenzil 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 ...?")Hames
I got a similar error message while trying to write c++ code inside c project (different configurations)Tiffaneytiffani
A
31

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.

Alyworth answered 28/2, 2013 at 16:46 Comment(3)
The linker really should check for this case and tell you that there is an unmangled version of the function defined!Latinalatinate
@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.Saddleback
@Saddleback 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.Canaan
S
26

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

g++ main.c function_file.c
Shamble answered 9/11, 2010 at 4:12 Comment(2)
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 #3202636Pitch
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.Deficient
A
5

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.

Avocation answered 4/7, 2015 at 22:4 Comment(1)
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.Denysedenzil
T
2

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.

Triliteral answered 27/1, 2020 at 8:41 Comment(0)
D
0

As Paul said, this can be a linker complaint, rather than a compiler error. If you read your build output/logs carefully (may need to look in a separate IDE window to see the full details) you can dell if the problem is from the compiler (needs to be fixed in code) or from the linker (and need to be fixed in the make/cmake/project level to include a missing lib).

Drive answered 29/3, 2020 at 22:12 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.