I have the following files:
listDriverTest.cpp
src/List.cpp
headers/List.h
The include in List.cpp is
#include "../headers/List.h"
The include in listDriverTest.cpp is
#include "headers/List.h"
When I compile with the following statement,
g++ listDriverTest.cpp "src/List.cpp"
I end up with a fair number of 'undefined reference' errors, e.g.
listDriverTest.cpp:(.text+0x81): undefined reference to `List<int>::List()'
listDriverTest.cpp:(.text+0x8f): undefined reference to `List<int>::add(int)'
listDriverTest.cpp:(.text+0x9d): undefined reference to `List<int>::add(int)'
...
How should I properly use includes and compile these three files in order for the compilation to work properly? I have gotten listDriverTest.cpp to compile and run properly with all the files in the same directory, but not when they're broken up like this.
See my answer in Must a child of a template class also be a template class?.
It is probably a different question, but the same answer applies.
It looks like the object file produced by compiling src/List.cpp already contains the specialization List, but it's in a different directory than the object file of listDriversTest.cpp. Hence, the linker cannot find it.
Of course, this depends on how you've organized your template code.
Your program compiled properly on my machine.
Just remove the double quotes around src/List.cpp
I think your problem is something else.
I added a function void list(void) in list.cpp which printed "list".
The same signature was added to list.h.
Related
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
I'm an experienced programmer, but only in high level languages; I'm doing my first really large project in C++ right now.
I've got two classes, ClassA and ClassB; a ClassA is (among other things) an index of ClassBs, so ClassA needs to know what a ClassB is to build arrays out of it, and a ClassB needs to know what a ClassA is so it can update the index when something changes. Both of these classes are in their own .h & .cpp files.
I figured including each from the other would just cause infinite recursion, so I decided to instead have #include "ClassA.cpp" and #include "ClassB.cpp" at the beginning of main.cpp; but doing this just caused the compiler to warn about multiple definitions of every class and method in those files.
After some experimentation I found out that including ClassA.h and ClassB.h produces the desired behavior - but this doesn't make any sense, I'm only including the prototypes of those classes. Surely the code that actually makes them up never gets mixed in? And yet it does.
What's going on here that I don't understand? Why does including ClassA.h also make the actual code for ClassA show up with it? And why does including ClassA.cpp cause every include of ClassA.h to trigger "multiple definition" errors even though they're in a header shield or whatever it's called?
The missing step is that the definitions in ClassA.cpp and ClassB.cpp will not be seen by the linker unless those files are also compiled at some point. If you did something like this:
g++ main.cpp ClassA.cpp ClassB.cpp
then all references to definitions in ClassA.cpp and ClassB.cpp from main.cpp would be resolved. However, if you only did
g++ main.cpp
then the linker would have no idea where to find the definitions in ClassA.cpp and ClassB.cpp and you would probably get an error.
If you're using an IDE, this detail is hidden from you: the IDE ensures that as long as you add a .cpp file to your "project", it will be compiled into the final binary when you build the project.
This is the way how C++ is designed:
Your classes don't need to now anything more than the prototypes of other classes, so you don't have to include more than the headers.
Why is this so? Well, compilation of an entire application is the combination of two steps: compilation of the code itself and then linking (actually, there is a third step preceding these: pre-processing, but we could consider this one as part of code compilation).
Example function call: It is sufficient (exception: inline functions!) to know that a function with a specific proto type exists. The compiler then can generate all the code necessary to do the function call, except for the actuall address of the function - for which it leaves some kind of place holder.
The linker then combines all code generated during the compilation step to a single unit. As now knowing where every function is located, it can fill their actual addresses into the place holders, wherever they may appear.
C++ code is compiled to *.obj for per .cpp file, and it is the link process make the obj files to an executable.
Never include *.cpp because it usually causes redifinition issue.
For each *.h file, add a macro to avoid multiple including:
#ifndef XXX_H
#define XXX_H
//your code goes here
#endif
The simple C++ code I wrote below got compile error
"undefined reference to 'featureExtract()'" (using codeblocks under windows),
in FeaureExtract.h
#ifndef FEATUREEXTRACT_H_INCLUDED
#define FEATUREEXTRACT_H_INCLUDED
extern void featureExtract();
#endif // FEATUREEXTRACT_H_INCLUDED
in FeatureExtract.cpp
#include "FeatureExtract.h"
void featureExtract()
{
some code
}
in main.cpp
#include "FeatureExtract.h"
int main()
{
featureExtract();
}
I have searched the SO using keyword "C++ undefined reference to" and read tens of entries (many are to class or under Linux), but I could not get my own problem addressed (I don't know why).
Thanks for any hint~
Before solving this problem, I have no choice but put all the staff in FeatureExtract.h, it works, but it seems not good. This post ( Why have header files and .cpp files in C++? ) explains the main merit of .h files is "separating the interface from the implementation", I wonder if putting all interface and implementation in .h files will have other effects?
Thank you~
It looks like you aren't linking both object files together into your final binary. Unfortunately I'm not familiar with codeblocks, but make sure all the .cpp files are added to your project.
Another less likely possibility is that somehow the name decoration is different between the two cpp files. Make sure you're using C++ to compile both files and that one doesn't compile as C code for example.
The code you posted looks fine. As Zeta said, are all files in the same project?
I get this error while compiling:
error: aggregate 'X x' has incomplete type and cannot be defined
I have three classes in 6 different files(header file + 3 implementation files). when I try to compile all these classes with a main, It gives me the above error. I am not including any header file in other header files, I am doing that in implementation files. So, I think its not a case of "cross reference". I am not sure what is the problem with my code can anyone help me in that?
Thanks
Somehow, that class isn't being defined when it needs to be.
Firstly, make sure the header has actually been included. Further, make sure you have include guards, and that you don't have circular includes and recursive definitions. Aside from that, without the code we cannot give specifics.
I came across this error trying to compile a shared object from 2 sets of objects. The first set contains one .os object compiled from one cpp file generated by SWIG. The second set is contains all of the .so files from the individual files that make up the interface to be wrapped.
$g++ -shared *.os -o Mathlibmodule.so
ld: duplicate symbol std::vector<int, std::allocator<int> >::size() constin Mathlib_wrap.o and Capsule.o
The swig c++ wrapper (Mathlib_wrap.o's source file) is machine generated and nasty to look at, with lots of #defines to make it extra hard to trace. It looks like the redefinition is present in all of the object files in the second set. I've traced through the headers included in all those files, and the seem to be #pragma once'd.
What advice do people have for tracking down what/where the problem is?
I'm going to assume that you've properly #ifndef/#define blocked all of the header files in your C++ library, after that I'd check your .i file to make sure you aren't actually duplicating some declaration there somehow. Maybe try importing a small small piece of the library first or something.
I have run into issues like this before, but its always turned out to be something silly I'd done. Nothing specific I'm afraid.
Post the .i file maybe, donno.
When in doubt, assume that the error means what it says: Actual code was generated for vector<T>::size within each of those object files. This of course seems very unusual because you would expect the function to be expanded inline in each file it was being used in.
If it weren't std::vector the first thing I would say is that a function defined in a header wasn't marked inline correctly. The compiler would generate the code in each source file that included that header. What version of g++ are you using, and are you using a custom standard library/vector implementation?
One thing to check is to compile with optimization on (-O2) and see if that causes it to inline the calls within creating an actual function.
Another possibility is that you're including two different versions of the vector include, and violating the one definition rule. At that point I wouldn't rule out a linker error such as you're seeing.