Most of the people who work on UNIX will face this irritating error often.
and some times it will take less time to solve and sometimes it will take hell lot of time.
Even i faced this regularly and i need some good document or an article regarding the specific error in c/c++
what are all the cases where there might be Symbol not found/Undefined Symbol error.
Could anybody help me to know what are all those cases?
The error is not related to UNIX/Windows/any other OS, but rather to the languages themselves. It is actually rather simple to diagnose with the information that compilers provide. Usually they will tell you what symbol is missing and sometimes where it is being used. The main reasons for a symbol to be missing are:
You have declared but never defined it
You have defined it, but did not add the compiled symbol (object file/library) to the linker
It is external and you forgot to link the library, or you are linking an invalid version, or in the wrong order.
The first one is a little trickier if you intended to define the symbol but did not match the declaration (declared void foo( int, double );, but defined void foo( double, int ). As with all other cases, the compiler will tell you the exact signature that it is looking for, make sure that you have defined that symbol, and not something close or similar, a particular corner case can be if you are using different calling conventions in the declaration and the definition, as they will look very similar in code.
In the case of libraries external code the complexity is in identifying what library needs to be linked for that symbol to be added, and that comes from the documentation of the lib. Beware that with static libraries the order of the libs in the linker command line affects the result.
To help you in finding what symbols are actually defined you can use nm (gcc, which is common among unix systems). So basically you can run nm against the object files/libs that you are linking and search for the symbol that the linker is complaining about. This will help in cases where the order is what makes the difference (i.e. the symbol is there, but the linker skipped it).
At runtime (thanks to Matthieu M. for pointing it out) you might have similar issues with dynamic libraries, if the wrong version of a library is found in the LD_LIBRARY_PATH you might end up with a library that does not have a required symbol.
Although they can be platform dependent, I have some "more complex" instances of some of the points from Andreas and David:
When dealing with shared libraries (.so or.dll) and linking against symbols which are not exported (dllimport/dllexport on Windows and visibility("default") with GCC on *nix)
Or similar: Linking against the static lib, while expecting a shared lib or vice versa. This one is bit similar to Mathieu's comment about linking against another, unexpected version of the library.
Creating a pure virtual classs and not providing an implementation for at least one method (causing no vtable to be available).
Actually a more complex case of declaring but not defining: The linking errors you can get when dealing with large, nested templates. Finding out what was not defined can be difficult with large error messages.
For most cases when you get a symbol not found/undefined symbol or sometimes even a "duplicate symbol" error, they usually stem from the fact that the linker is unable to find the symbol in the project that you are trying to build.
The best way to go about it is to look at the map file generated or a symbol table that is the output of the compiler. It may look something like this:
This will allow you to see if the symbol is present or not. Also, there might be other esoteric problems such as compiler optimizations that might cause a symbol duplication especially with inline assembly. These are about the hardest to detect.
As for good resources and materials, I don't have many good references. When I did ask around back then, most of the senior engineers have actually learned from their own experiences.
But I'm sure that's where forums such as these are present to help us expedite such knowledge acquisition.
Hope it helped :)
Cheers!
I assume you're referring to the linker error. Here's a list from the top of my head in what I think most-to-least common:
You forgot to tell the linker about a dependency (e.g. a LIB-file).
You have a class with a static data member and forgot to initialize it (only C++).
You declared a function not purely virtual and forgot to implement it.
You forgot to implement a function that you called from another function (only C, C++ will give a compiler error which is much easier to find).
You declared an external variable and forgot to initialize it.
The declaration of the function doesn't match the implementation (only C++, C will accept it and might die horribly).
You forgot to implement a function that you declared and called from another function.
Related
I'm currently updating a C++ library for Arduino (Specifically 8-bit AVR processors compiled using avr-gcc).
Typically the authors of the default Arduino libraries like to include an extern variable for the class inside the header, which is defined in the class .cpp file also. This I assume is basically to have everything provided ready to go for newbies as built-in objects.
The scenario I have is: The library I have updated no longer requires the .cpp file and I have removed it from the library. It wasn't until I went on a final pass checking for bugs that I realized, no linker error was produced despite the fact a definition wasn't provided for the extern variable in a .cpp file.
This is as simple as I can get it (header file):
struct Foo{
void method() {}
};
extern Foo foo;
Including this code and using it in one or many source files does not cause any linker error. I have tried it in both versions of GCC which Arduino uses (4.3.7, 4.8.1) and with C++11 enabled/disabled.
In my attempt to cause an error, I found it was only possible when doing something like taking the address of the object or modifying the contents of a dummy variable I added.
After discovering this I find its important to note:
The class functions only return other objects, as in, nothing like operators returning references to itself, or even a copy.
It only modifies external objects (registers which are effectively volatile uint8_t references in code), and returns temporaries of other classes.
All of the class functions in this header are so basic that they cost less than or equal to the cost of a function call, therefore they are (in my tests) completely in-lined into the caller. A typical statement may create many temporary objects in the call chain, however the compiler sees through these and outputs efficient code modifying registers directly, rather than a set of nested function calls.
I also recall reading in n3797 7.1.1 - 8 that extern can be used on incomplete types, however the class is fully defined whereas the declaration is not (this is probably irrelevant).
I'm led to believe that this may be a result of optimizations at play. I have seen the effect that taking the address has on objects which would otherwise be considered constant and compiled without RAM usage. By adding any layer of indirection to an object in which the compiler cannot guarantee state will cause this RAM consuming behavior.
So, maybe I've answered my question by simply asking it, however I'm still making assumptions and it bothers me. After quite some time hobby-coding C++, literally the only thing on my list of do-not's is making assumptions.
Really, what I want to know is:
With respect to the working solution I have, is it a simple case of documenting the inability to take the address (cause indirection) of the class?
Is it just an edge case behavior caused by optimizations eliminating the need for something to be linked?
Or is plain and simple undefined behavior. As in GCC may have a bug and is permitting code that might fail if optimizations were lowered or disabled?
Or one of you may be lucky enough to be in possession of a decoder ring that can find a suitable paragraph in the standard outlining the specifics.
This is my first question here, so let me know if you would like to know certain details, I can also provide GitHub links to the code if needed.
Edit: As the library needs to be compatible with existing code I need to maintain the ability to use the dot syntax, otherwise I'd simply have a class of static functions.
To remove assumptions for now, I see two options:
Add a .cpp just for the variable declaration.
Use a define in the header like #define foo (Foo()) allowing dot syntax via a temporary.
I prefer the method using a define, what does the community think?
Cheers.
Declaring something extern just informs the assembler and the linker that whenever you use that label/symbol, it should refer to entry in the symbol table, instead of a locally allocated symbol.
The role of the linker is to replace symbol table entries with an actual reference to the address space whenever possible.
If you don't use the symbol at all in your C file, it will not show up in the assembly code, and thus will not cause any linker error when your module is linked with others, since there is no undefined reference.
It is either an edge case behaviour caused by optimization, or you never use the foo variable in your code. I'm not 100% sure it is formally not an undefined behavior, but i'm quite sure it isn't undefined from practical point of view.
extern variables are implemented in such way, that code compiled with them produces so-called relocations - empty places where addres of variable should be placed - which are then filled by linker. Apparently foo is never used in your code in such a way that would need getting it's address and therefore linker doesn't even try to find that symbol. If you turn optimization off (-O0) you will probably get linker error.
Update: If you want to keep "dot notation" but remove the problem with undefined extern, you may replace extern with static (in header file), creating separate "instance" of variable for each TU. As this variable is going to be optimized out anyway, this will not change the real code at all, but will also work for unoptimized build.
So, usually when you see an Unresolved External Symbol error, the linker at least tells you what function the reference is in, i.e.
unresolved external symbol "class1::function1" **referenced in function "class2::function2"**
But what do you do when you only get the first half? i.e.
unresolved external symbol "class1::function1"
I know where "class1::function1" is defined, and I am deliberately not including it. So just including the file containing the definition won't help. The include is ifdef'd out, along with all references to symbols contained in the file. What I need is a way to locate the reference to this deliberately non-included symbol so that I can get rid of it. Searches for the name of the symbol reveal only things which I have already ifdef'd out.
If it's a virtual function then it's referenced from the vtable, which in turn is referenced from each constructor (or each place where a constructor is inlined).
If you're using instances of the class I think your best bet is to remove the virtual keyword. Otherwise you must provide a definition, even if only a stub.
(The language standard handles this by considering any virtual function as always used, so a definition is required.)
I'm not sure why that happens, but easy way to determine source of problem is to comment out all declarations of class1::function1, and rebuild the project - compiler will complain whenever class1::function1 is called on compile stage instead of linking.
This turns out to have been a combination of a mistake on my part, and a non-helpful error message. One of the classes was missing a member of it's inheritance chain.
Personally I would have expected this to result in a compiler error ("Extending Undefined Base Class" or something similar), but instead I got linker errors for the virtual functions in said base class (despite that class not being included). But because no functions were actually referencing them, the linker could not provide a "referenced in" section for the error message. I still don't entirely understand why this set of problems with the code gave that set of error messages, but I was able to fix it.
Thank you Alan for your input, it got me looking in the correct direction. I would upvote you, but having joined immediately before posting the question, I lack the reputation score to do so.
This question already has answers here:
What is an undefined reference/unresolved external symbol error and how do I fix it?
(39 answers)
Closed 9 years ago.
I'm trying to wrap my head around C++ developement using the SFML library. I'm following a tutorial (http://www.gamefromscratch.com/page/Game-From-Scratch-CPP-Edition-Part-7.aspx), and using visual studio 2010.
A problem I keep running into regards unresolved externals. I'm really struggling with this, because unlike most errors I run into, it doesn't seem to a) have anything to do with the code, and b) doesn't behave consistently. Rather than give y'all a specific example and ask for help solving that one example, I'm hoping to develop a more reliable way of attacking these problems. I'll give you an outline of a common occurance though.
I have a solution with 8 header files and 8 cpp files that correspond to them. The solution is stable: It compiles and runs with no errors or warnings.
I'll go into a header file and add this line:
virtual void DoNothing();
I'll then go into the matching cpp file and write the method:
void DoNothing(){};
I compile and run, and get 5 unresolved external errors. They don't point to any line of code, so I don't really know how to fix them, but I obviously did something wrong. Fair enough. Trying to get back to a stable state, I delete the two lines of code I had inserted, and compile. Even though the code is identical to the last stable state, I get the same unresolved external errors.
Trying random things, I go into another cpp file and reverse the order of two included header files. The game compiles now. If I switch the order of the included header files back, it compiles.
What the hell are unresolved external errors? Why don't they seem to behave consistently with the code I've entered? How do I read them to find out what the problem is, and how do I avoid them in the first place?
Thank you.
ps: If there are more specific details I should provide, please just let me know.
"Unresolved External" errors mean that your code is referring to something (usually a function or method, but can be a variable too) that does not exist. These are link errors, and not compile errors; that's why you don't get a line number and more helpful error messages.
Let me give you a little background on how C++ code is turned into an executable (and keep in mind that I'm simplifying things a bit.)
Each C++ source file (and not header file) in your project is compiled separately. A ".cpp" file and all the headers it includes are compiled into what is called an object file or object code. (These files have a ".obj" or ".o" extension.) You can also think of library files (that is ".lib" files on Windows and ".a" files on Linux) as a collection of these object files, stored for later use.
To produce the executable programs (e.g. the EXE or DLL file on Windows) all these object files are linked together are voila!
Now, the important thing here is that each source file is compiled in isolation and independent from other source files. So, if the code in one file calls a function that is implemented in another file, the compiler won't see the actual body of that function and can only assume that as long as the declaration of the called function is visible (i.e. the prototype, i.e. the line you write in headers,) then these files are going to be linked together eventually and will leave the task of actually making the call to the linker. This usually means that as long as you include the right headers, your compiler is going to be happy.
But the linker is going to be more tenacious and pedantic. At link time, you really really need to provide the body (i.e. the implementation) of all the functions that you use all over the project. It is your task to make sure that all the right object files and libraries are linked together and the implementation of each used function exists somewhere among them exactly once (no more, no less.)
This brings us to your problem. When you get an "unresolved external" linker error, this means that the body of a function you've called does not exist anywhere in object files and libraries that you are linking together.
Obviously, one of two things is happening. Either you have included the header for an external library, but have forgotten to link in the library file itself (which is not your problem here) or you've declared (i.e. written the prototype for) a function but have forgotten to implement its body.
Keep in mind that the linker is really strict here. If you declare something like this in your class:
class Foo {
void bar (int x);
};
and then in your ".cpp" file, implement this function:
void bar (int x)
{
// Do nothing
}
then you'll get an unresolved external error if you actually call Foo::bar() anywhere in your program, because the implemented bar() is not a method of Foo (you should have implemented void Foo::bar (int x) {}.) Similar things happen if you slightly misspell or get the type of the arguments wrong or whatnot.
Reading linker errors and making sense from them can be hard. Sometimes, the name that the linker is complaining about (the "symbol" it says it can't find) is all mangled beyond recognition. This has to do with *Application Binary Interface*s (ABI) and several decades of history and precedence. Anyways, most of the time, if you look closely and the link error message, you can see what the function name was and check your code (or libraries) and try again.
Also, though it's rare, it sometimes happens that in order to solve some link issues, you have to resort to completely rebuilding your project.
Every time I've seen behavior like this it has been because of a circular reference between projects. For example, project A has a reference to an object/symbol implemented in project B while at the same time project B has a reference to an object/symbol from project A. Every time you build your solution, the tools have to compile one project first, then the other. If you make a change to the second project to be compiled, the first one cannot see the change on the first round of compilations and the build fails. If you manage to manually build project B (against a now obsolete copy of library B), then the solution starts to build correctly. More complex cycles are possible (e.g. A depends on B, which depends on C, which depends on A). You don't mention multiple projects explicitly, but I bet you have them.
These circular references are common on large solutions that have been around for a long time and have grown slowly over time. People get in habit of adding links from everything to everything because they need one function from here, a struct from there...
Hunt down these dependencies. You should be able to do a full clean rebuild from nothing but the source code. Your dependency tree should look like... Well, a tree; not a graph.
Compilers these days tend to do a significant amount of optimizations. Do they also remove unused functions from the final output?
It depends on the compiler. Visual C++ 9 can do that - unused static functions are removed at compilation phase (there's even a C4505 warning for that), unused functions with external linkage can be removed at link phase depending on linker settings.
MSVC (the Visual Studio compiler/linker) can do this if you compile with /Gy and link with /OPT:REF.
GCC/binutils can do this if you compile with -ffunction-sections -fdata-sections and link with --gc-sections.
Don't know about other compilers.
As a general rule, the answer is:
Yes: for unused static functions.
No: for unused globally available functions.
The compiler doesn't know if some other compilation unit references it. Also, most object module types do not allow functions to be removed after compilation and also do not provide a way for the linker to tell if there exist internal references. (The linker can tell if there are external ones.) Some linkers can do it but many things work against this.
Of course, a function in its own module won't be loaded unnecessarily by any linker, unless it is part of a shared library. (Because it might be referenced in the future at runtime, obviously.)
Many compilers do, but it depends on the particular implementation. Debug builds will often include all functions, to allow them to be invoked or examined from within the debugger. Many embedded systems compilers, for reasons I don't totally understand(*), will include all of the functions in an object file if they include any, but will omit entirely any object files that aren't used at all.
Note that in languages which support reflection (e.g., Java, C#, VB.NET, etc.) it's possible, given the name of a function, to create a reference to it at runtime even if no references exist in the code. For example, a routine could accept a string from the console, munge it in some fashion, and generate a call to a function by that name. There wouldn't be any way for a compiler or linker to know what names might be so generated, and thus no way to know what functions may be safely omitted from the code.
No such difficulty exists in C or C++, however, since there is no defined way for code to create a reference to a function, variable, or constant without an explicit reference existing in the code. Some implementations may arrange things so that consecutively-declared constants or variables will be stored consecutively, and one might thus create a reference to a later-declared one by adding an offset to an earlier-declared one, but the behavior of such tricks is explicitly not guaranteed by the C or C++ standards.
(*)I understand that it makes compiling and linking easier, but today's computers should have no trouble running more sophisticated compiling and linking algorithms than would have been practical in decades past. If nothing else, a two-pass pre-compile/pre-link/compile/link method could on the pre-compile/link phase produce a list of things that are used, and then on the "real" compile/link phase omit those that are not.
GCC, if you turn on the optimizations, can remove unused functions and dead code.
More on GCC optimizations can be found here.
Quite a lot of the time, yes. It’s often called linker stripping.
When it comes to Microsoft, it's the linker that takes care of this during the link phase and the compiler might warn you about unused static functions (file scope).
If you want the linker to remove unused functions, you use the /OPT:REF option.
Under MSVC and with global functions or variable you can use __declspec( selectany ).
It will remove the function or variable if it has not being referenced in the code if the linker option /OPT:REF (Optimizations) is selected.
What's the difference between the following two declarations? I thought they were equivalent, but the first sample works, and the second does not. I mean it compiles and runs, but the bitmap display code shows blank. I have not stepped through it yet, but am I missing something obvious? GUI_BITMAP is a simple structure describing a bitmap. This is for VC++ 2005, but I think it fails in VC++ 2008 also. Scratching my head on this one...
Sample 1:
extern "C" const GUI_BITMAP bmkeyA_cap_active;
extern "C" const GUI_BITMAP bmkeyA_cap_inactive;
Sample 2:
extern "C"
{
const GUI_BITMAP bmkeyA_cap_active;
const GUI_BITMAP bmkeyA_cap_inactive;
};
Edit: More exploring has shown that the second example is creating the structs, while the first is referring to external structs. The second example should fail to link, since there are two variables at global scope with the same name. But it doesn't, it sends a zero filled struct to the display code which gives up. Hmmm.....
Edit 2: Running the same code through another compiler (IAR) actually failed to compile on Sample 2, with an error about missing a default constructor. So I'm guessing there is something subtle about the "extern" keyword, structs, and C++ that I don't get. If the things in extern area were functions the two samples would be identical right?
Your linker may is silently resolving the duplicate symbols behind your back. You might get static libraries from a vendor and have to link them with your program - what is the solution for the situation where you have two such libraries and they both define a common symbol? The linker will just resolve that, choosing one or the other definition, and leaving you to deal with the fallout. How are you handling the link stage of your application? You may have better results if you link .o files directly instead of putting them into intermediate libraries before linking the final application.
This page of the ARM documentation describes the problem well - I expect similar behaviour is happening in your case:
Multiple definitions of a symbol in different library objects are not necessarily detected. Once the linker has found a suitable definition for a symbol it stops looking for others. Assuming the object containing the duplicate symbol is not loaded for other reasons no error will occur. This is intentional and particularly useful in some situations.
Edit: More searching has turned up that this problem is caused because of a violation of the "One Definition Rule", and as a result the compiler/linker aren't required to inform you of the problem. That makes your question a duplicate of this one.
The second example might be equivalent to the first with an extra extern in front of the const. In the first case, the compiler is probably combining the two uses of extern. In the second case, I would assume the compiler doesn't male everything in the extern scope extern for whatever reason.