Undefined reference error to function in other file [duplicate] - c++

This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed last year.
I have a game program and I am getting VERY frustrated. Everything was running fine, and I decided to clean up my program by making separate files for each set of functions. The code is very long with multiple files, but heres the basic idea:
Im on Windows XP using the Code::Blocks IDE
In my entity.h Ive declared all of my functions and variables for that class. In my entity.cpp Ive included it, as well as in all my other files. But Im still getting a huge list of errors that tell me I have an undefined reference to all of the methods in entity.h as well as all my other header files. For example, I have a function call print() to make it easier to print out things, and thats the first method I call from the entity.h file. I get this error:
Heres the code for print():
void print(string f) {
cout<<f<<endl;
}
How Im calling it:
void Player::win(){
entity e;
e.print("You have defeated the orc");
}
The error:
In function 'ZN6Player3winEv':
undefined reference to 'entity::print(std::string)'
And yes, I do have an object of entity.

Undefined reference errors happen at link time (as opposed to compile time). Your code seems to be compiling correctly, so your headers are probably correct. But you're not linking everything together to make the executable. You didn't mention the platform, compiler, or build system, so I can't tell you exactly how to fix it, but in general the compiler generates a *.o file for each *.cpp file (that's the compilation) and then links the *.o files together to create an executable. You need to make sure all your *.o files are being linked together (also, you might not be compiling one of your *.cpp files into a *.o file).

At a quick guess, you're not linking the entity.o file to the binary.
If you're using linux g++, then something like:
g++ -o binary entity.cpp game.cpp
should compile and link the cpp files to the binary.
For Code::Blocks to select the files that are within a specific build group, you need to right-click on the target application and select properties. This will pop-up the Project/target options. Go to the Build Targets tab. Towards the bottom-right of the page is a list of Build target files. You need to make sure that all the files that contribute to the executable are selected as part of your build target. This means that you need a check-box on the entity.cpp file. This ensures that the file that contains the code for entity::print is compiled and linked into the target executable. Please note that the Build target files tab applies to the selected build target in the list at the left-hand side. You will need to ensure that the file is checked for all the build targets that it belongs to.
In general, when you're adding files in Code::Blocks, and where you see the check-boxes for the targets that the file should be added to you should make sure that all the targets that the new file belong to are checked. The default from the wizard is to leave all the check-boxes unchecked. In your case, as it's a simple project, you should make sure that it is checked for each target (typically it will start with debug and release as the two targets).

I had the same problem. For me the solution was :
When you add a file in your project, dont forget to click on "add to DEBUG" and "add to RELEASE", either the file will be in the project tree yes, but you will have error "undefined reference"

The problem is that originally you were defining a free function named print instead of a member function named print of class entity. You need to be in the scope of the class entity to define it as a member function which is what i did using scope resolution operator :: below.
/////vvvvvvvv
void entity::print(string f) { //note the scope resolution operator:: used here
cout<<f<<endl;
}

Related

Undefined reference to 'Winmain#16' and ld returned 1 exit status codeblocks c++

I am working on a programming project for an assignment. I have a class and I have to make it an ADT so I have to split the program into the interface, implementation and main project. This means I'll have 3 files. I am using codeblocks 16.01 and I tried solving the problem by downloading the codeblocks v20.03 but it did not work. My program works fine in one file but when I split it into 3 files, I get two errors:
Undefined reference to 'Winmain#16'
ld returned 1 exit status
I have read almost all the threads and tried practically everything I've read from simply closing and reopening the program to going to Settings>Compiler>Linker Settings but that did not work. Some suggested on threads that the program is not a console so I should create it as a console and I did that too but nothing worked. In fact I just create empty class and save it as main.cpp then I go to create a new class, I name my new class and uncheck "Has virtual Destructor" and I also uncheck "Virtual Destructor". I make the directory the same folder as my main.cpp and then I copy the header file to the main.cpp program try building it then I get the errors. I don't do any coding yet I'm receiving these errors.
If you can, please help by providing direct instructions because I did read a lot of threads and tried fixing this but none has worked for me
Thank you.
The error in my initial post appears when you create multiple files incorrectly. The way multiple files are supposed to be created is as follows; or to fix the error, follow these simple steps:
You're first to go to create a project of type Console Application. Once that's done, you won't have any files open, you'll just see the name of your Console Application at the top.
Next, go to create a class. Once you've done that and have named your class, you'll be asked if you want to add it to your current project. You should select the yes button to add it to your current project. You will then have a .h and .cpp file.
Your main.cpp file by this point will have already been created for you. Simply go to open and find your project folder. In that folder you'll find your class files and main.cpp files. Open the main.cpp file. If you're asked to add it to your current project, click the yes button and you're good to go!

Undefined reference error in C++ using Cygwin, why aren't my files linking?

I have a series of files from a shared github project and they run perfectly for everyone else. But everytime I run them I get a
"CMakeFiles/Dice.cpp.dir/Player.cpp.o: In function Player::Player(std::string)':
/cygdrive/c/Users/Abby/CLionProjects/Risk_Domination/Player.cpp:51: undefined reference toDice::Dice()'"
error. Dice is the only class that I wrote on my computer. It is included in all the files it is used in, I don't know why the two won't link. I get the same error again the next time I refer to the variable dice.
The file player, which is getting the error, includes everything below. And the class Dice does include a constructor Dice(), which is defined and has been tested.
#include "Dice.h"
//and errors are pointing to line 51:
this->dice = new Dice();
//and line 81
a = dice->rollDice(number_of_dice);
You mention that everything work perfectly for others, but for you it doesn't work, specifically for the file you wrote on your PC. For clarification: Can other people compile with Dice?
If you have a linking problem, it is likely that the .cpp file is not set to be compiled with the executable in CMake. This tells me that the issue is in the CMakeLists.txt file, not in any sourcefile.
To fix the issue make sure that the executable or library that you want Dice to be part of includes the Dice.cpp file in the add_executable or similar function.

What is __aeabi_unwind_cpp_pr1' and how can I avoid it?

I have a bunch of arm assembly, C and C++ files. gcc is trying to link them, but these are for an embedded project.
I am not using any external libraries, all code that is being used was written by me. An error seems to happen because I have a function called int kernel_main(void) defined in main.c that is trying to call set_LED(int value) defined in mailbox.cpp which includes the header mailbox.h (I did include the header in the main.c file).
The exact error is:
undefined reference to `__aeabi_unwind_cpp_pr1'
The way I am making my project is:
-compile all source files (.s, .c, .cpp) into object files (.o) without linking (-c), then link them all together with the use of a custom linker script.
Edit: I am going to add some information to make things more clear.
First changing all files so that all of them are C files (no cpp extensions) yields:
undefined reference to `set_LED'
It is unlikely that the issue itself is name mangling an it probably has nothing to do with CPP and C differences.
The problem is very likely to be a linker issue
This is the build process:
Compile c files, Example:
arm-none-eabi-g++ -O0 -march=armv8-a source/MainFiles/mailbox.cpp -nostartfiles -c -o objects/MainFiles/mailbox.o
(Compiling a C++ file would be identical except for the use of g++ instead of gcc)
Link everything:
arm-none-eabi-ld object1 object2... -o build/kernel.elf -T ./source/kernel.ld -I include_directory_1 -I include_directory_2 -L include_directory_1 -L indlude_directory_2
Include directories are all directories under the current one
Edit:
The error came back. Ignore the parts of this question relevant to name mangling. The error I need to fix is:
./objects/Hardware/mailbox.o:(.ARM.exidx+0x18): undefined reference to `__aeabi_unwind_cpp_pr1'
So far all I know is that this has something to do with unwinding the stack and exceptions. It seems the function is defined in libgcc. However I have used -nostdlib, I have omitted it, and in both cases the error persists. I have tried changing file extensions to .c whenever possible and to .cpp whenever possible, alas the error is always there.
It got fixed only as long as I had exactly 1 cpp file and the rest of my files were C files (this is no longer true, I tried). What triggered the error again was that I was refactoring the code and I wanted to move a couple of functions to new files.
In other words, without deleting a single file, declaring a function named wait(uint32_t time) in mailbox.cpp works, declaring it in a file called time.c (or cpp) with it's respective header declaration and including the header in mailbox.cpp breaks things. Note I don't delete the files when moving the function I simply delete the function declaration inside each file.
Adding a stub like this:
void __aeabi_unwind_cpp_pr1()
{
}
Fixes the problem and the code works. But I don't like this solution. I don't want a useless stub being called mysteriously in my code. I don't need nor want this function in my current implementation, how can I tell the compiler or the linker that they are to omit whatever they are doing that requires this function?
The solution is very simple. As it turns out exceptions are enabled by default (which is what generates the code that calls __eabi_unwind_cpp_pr1). To disable them all that is needed is to pass:
-fno-exceptions as an argument to the gcc/g++ compiler and the problem is solved.
You have a reference to this function that belongs to the C++ runtime of GCC. It's part of the exception handling. Whatever you are doing, sounds a little crazy, but anyway you can do this if you really know what you are doing. You must link against the C++ runtime libraries. That's it. Link against "libstdc++".
About the set_LED I also believe it's just about the C++ mangling, just as Justin J mentioned in the other answer.
I have seen this when mixing C and C++. Because of name mangling, the symbols will have different names internally depending on the type of the source file.
If the source for 'set_LED'is a c file, use the following in the header around the prototype and see if it helps.
#ifdef __cplusplus
extern "C" {
#endif
// function prototypes here
#ifdef __cplusplus
}
#endif
Please also add prefix "-shared" without quotes to -fno-exceptions. I am using ARM GCC version

ImGui, SDL2 & code block, struggling to setup

since there is no real tutorial on how to setup ImGui & SDL2, I came here to find answers.
I just have to paste ImGui file into my include folder to setup it right ? At least, it is what the ImGui readme file says.
When i try this :
ImGui::Begin("test");
I have this error :
undefined reference to `ImGui::Begin(char const*, bool*, int)
Code block do autofill me with ImGui functions when I start to write 'i'. Also when I do #include other files (ImGui_draw, etc. ...), I got only redefinition problems.
=> That's why my question sis lighty different from the already answered following question :
What is an undefined reference/unresolved external symbol error and how do I fix it?
So please do not close this question. I'm looking for a solution from 2 day now and a question here is my only solution left. I will have to give up on ImGui if this question is closed.. I'm truly clueless.
Could this error be due to a conflict with SDL2's opengl ? But in this case, shouldn't just the program crash instead ?
EDIT : Now this error is solved(I used to work with an IDE who include itself the files in my include folder, I didn't knew code block didn't), I have my program launching but nothing related to ImGui happens (as expected, I didn't figured out yet how to mix SDL2 & ImGui) and another error happens now when I quit my SDL2 window :
The program crashes and display the following in the console :
Assertion failed: g.Initialized, file C:\(...)\imgui.cpp, line 3882
Some random testes: If I use ImGui before my main loop it crashes there. Same inside the loop.
I just have to paste ImGui file into my include folder to setup it right ?
No. The header files are needed for your app to see what symbols are out there for valid compilation. But during linking, those symbols actually need to be there, and adding a single header file is not going to add them. You need to bring all the source files (cpp files and probably their corresponding header files) into your app and compile it all together.
Building a C++ app has two main stages: compilation and linking. Your header path has all the information for the compilation stage, but not for linking. Only actual source files (which are not header files) can contain the symbols needed to define what is declared in your headers. If you don't add those too, then your symbols are not defined, which explains your error.
Code block do autofill me with ImGui functions when I start to write
'i'.
That's because you included the header file, which is one part of the process.
I got only redefinition problems.
And just in case you are doing this, don't use #include with any .cpp files, only header files. If you #include cpp files in more than one place, you will definitely get multiple definition errors, as you indicated.
Quoting from imgui's README:
ImGui is self-contained within a few files that you can easily copy
and compile into your application/engine:
imgui.cpp
imgui.h
imgui_demo.cpp
imgui_draw.cpp
imgui_internal.h
imconfig.h (empty by default, user-editable)
stb_rect_pack.h
stb_textedit.h
stb_truetype.h
So you don't only need the imgui.h header, you need all of these file, taking care of compiling and linking the cpp files into your executable.

Getting undefined reference error at adding simple class to library

I am working with a rather sizeable library which uses CMake for compilation/linking. I need to add some functionality, thus I need to add some classes to the library. The problem is that when I add even a simple helloWorld class to the library, and try to call it from some main function, I get undefined reference problem at link time. When I looked into the built code ("CMakeFiles" within the library folder), my class hasn't been compiled by CMake (and thus, for instance, there is no HelloWorld.o file in there).
Can somebody point out where I am going wrong? Do I need to explicitely tell CMake to compile this class? (if yes, how?). I am novice in CMake, so don't know how to tackle this problem.
I call the function like this.
``
GSROrdinary sord;
The error message, I get, is something like this.
undefined reference to beep::GSROrdinary::GSROrdinary()
undefined reference to beep::GSROrdinary::~GSROrdinary()
Yes, you need to tell CMake to compile your class. I suggest that you check out some CMake tutorials that can be found online. Here is a nice one: http://www.cs.swarthmore.edu/~adanner/tips/cmake.php - pay particular attention to the CMakeLists.txt file and syntax. You will have to modify your lib's CMakeLists.txt in order to add a new class.
You have to explicitly add your new file to the CMake file so that they get compiled and linked.
This commented sample could give you a start (basically you have to look for a add_library (LIBNAME files) directive in one of your CMakeLists.txt files and add your new file there, but you should also possibly read the documentation.