Undefined reference/unresolved external symbol errors in C++/C/Objective-c and ways to solve/avoid them.

These specific errors occur at the last stage of Compilation, The stage is also called linking stage. As the name suggest all the code(implementation files) has been converted into object file or libraries. Now compiler wants to link them all together.

for a small example, A developer has defined one symbol SYM in a class TEST1 and you declared it in class TEST2. Linking phase has the responsibility to make sure call to that symbol finds valid symbol and link to it. In case that symbol not found TEST1(due to various reasons Will talk about it in detail) we will get such error.

Following are some most common error people do result in such errors:

Forgot to Add Appropriate Libraries/object files:

This is one of the most common mistake, When a user does use headers of the library but forget to add related Library/object files or has an invalid path. In case of using development tools like Xcode forget to add library search path. So At the linking time, no such symbol found hence the error.

In Xcode, Go to Build Setting => Go to Library search Path => give path to the library. Similarly, GO to header search Path => give Path to the header

In terminal/Makefile, you have to specify all object files and all libraries using -l while creating a final executable/library. so the syntax would be like:

g++ -o outputFile objFile1.o objFile2.o -lmyLibries

While doing all that check if the developer has that valid symbol. if yes, check if developer has a valid path to it. The above example is assuming all .o and libraries are in the same folder.

In Microsoft Visual Studio, Go to Linker -> General -> Additional Dependencies

Mixing C with C++, Symbols defined in C called from C++:

C++ mangled names of functions and variables(Why: wiki). So the declaration of C functions in C++ becomes a bit tricky. And as the name of function/variable has changed in c++ file, The definition of function/variable will never be found hence linking error. Following is one example to do it in a proper way:

Let?s say we have a Method named void C_Method() and we want to use it in C++ file. So the Declaration on C++ should look like

extern ?C? void C_Method()

Adding extern ?C? tells compiler that this method belongs to C and don?t mangle it. But Wait what if you want entire header file to use? In that case, you have to extern complete header file like:

extern “C” { #include “your_c_header.h”}

Also, there is one more way to if your C library is your own you can directly do following in your header:

//At the beginning of you header#ifdef __cplusplusextern “C” {#endif//and following at the end#ifdef __cplusplus}#endif

So now you C file header managing them-self based on where they have been used. Still little confuse go here.

Declared but did not defined:

One of the most typical mistake, When programmer forgets to give definition to the method/variable. for example

int calculateCalories(int fatVolume);int main() {int cals = calculateCalories(500);return 0}//comment out this method and linking error will start int calculateCalories(int fatVolume){ return 0 }

Similarly for variables:

//file 1extern int myAwesomeVariable;bool isTrue(){ myAwesomeVariable = 10; return (myAwesomeVariable != 0) ;}//file 2int myAwesomeVariable; //remove this line and error will start, As //extern is only implies that the variable //exist, Not the definition itself.

C++ Templet Issues:

Undetermined/unspecialized templet must have their definition visible to all files that are using them. Which means, Do not separate implementation and declaration. And if in any case it is needed make sure implementation file added to the same group. And can be included easily. Example:

template<class T>struct MyStruct{ void templetMethod();};int someMethod(){ MyStruct<int> myStruct; myStruct.templetMethod(); return 0;}//different ImplFile => error, to fix MyStruct::templetMethod need //to move to it’s declaration.Or some place where it is visible to //all files, which are using it.template<class T>void MyStruct<T>::templetMethod(){}

Still confused. Here is detailed discussion.

Interdependent Linked Libraries

It is very important to maintain the order of association of library If they are interdependent. The linking need to be done in order of no dependencies to higher dependency.

Importing incorrect modules while working in multi-platform/multi-architect code base:

In multi-platform code, We generally segregate platform specific libraries using #defines and one misplaced #define can lead to tons of errors.

Similarly, If you are using fat file libraries. make sure they have all the architecture you are looking to use them for.

#in mac you can use following to get info about all the #architectures lipo -info yourLibs

Source file with the same name:

If source files are organized in different folder, then it is possible to have same name file in different folder, And Microsoft Visual Studio(Some versions) can?t handle it. As it keeps all .o file in flat single directory so new .o file replaces the older one. But it?s an old problem and may have been fixed. I don?t use windows. So, can?t say much in it.

And many more? But if all fail, try to clean all object file and recompile.

14

No Responses

Write a response