[Note: If you do NOT find what you were looking for in this article, please leave a comment. I'll update as necessary to keep the information accurate, useful and current.]
Once upon a time, I was a graduate student at UC Berkeley, and spent a fair bit of time in the engineering library. I recall picking a smallish book from the new acquisitions shelf once, on the subject of linkers. The title escapes recall, but the introductory blurb made a distinct impression on me at the time. It went something like this (paraphrasing, obviously):
Linkers really suck, because the technology is not taught in the computer science curriculum, and everyone hates linkers because linkers are boring. Thus, an ambitious young computer scientist may find a large amount of opportunity in creating linker technology.
While those surely weren’t the exact words the author used, the above was the meaning I took from it. Of course, I put the book down immediately, recognizing the dual snake pits of distraction and temptation.
The time has now come: while as the commenter quoted in my post below notes, it may not be possible to understand linking without writing a linker, I personally think his post is a bit of a cop-out, that anyone can learn a fair bit about linkers (especially what linker warnings mean) without having to write a linker. Specifically, I believe anyone can learn to fix linker errors efficiently without pawing through the man pages, googling specific instances of linker errors, or hacking the linker source code.
Onward, through the fog. — Oat Willy
—-
A Rogue’s Gallery
Probably the most common linker error is error LNK2001: unresolved external symbol, given here as a result from Microsoft Visual Studio. This means the linker cannot find any executable to invoke for a particular function. The two most common cases in my experience are with 1. c and 2. c++ (I am a c/c++ coder after all).
With c, there are 2 general cases:
- The function is defined in the header but not implemented in any source file. This situation is very common when developing your own libraries and writing your own code.
- The function or method is implemented but the compiler cannot find the object file or library to link to. This occurs with astounding frequency when using 3rd party source code or libraries, inducing much wailing, gnashings of the teeth and pullings of the hair.
Neither of these situations are that difficult to fix. Case 1 requires checking each source file including the specific header file (it did compile, right?), and adding the requisite function or method in the appropriate place. Case 2 is a bit more difficult, and may require some poking around in the either the A. include path for libraries (say, -L/usr/local/lib/cooltool), and B. making sure the library is specified for linking (e.g., -lcooltool.a). Given these are both satisfied, checking the library object with ar (unix) is usually sufficient to determine whether the function in fact exists in the library. If it doesn’t exist, check for version number of the library, forwards and backwards, and whether the compiler flags were set correctly when the library was compiled (if possible).
With c++, the same 2 cases occur, with the complication of arbitrary name mangling added to support polymorphism, etc. Proceeding intelligently from here requires a detour (i.e., a “long cut” vice short cut) through the intricacies of name mangling.
c++ name mangling
In the c++ world, polymorphism (etc.) requires handling functions and methods having identical names, a situation explicitly not allowed in c. Various schemes for resolving identical names into unique calls are implemented in compilers. “Various” is a bit of an understatement. A more accurate statement is that each compiler rolls it’s own scheme. The result of this is that objects compiled using different compilers typically cannot link against each other. Cross-compiling is a different topic, we’re not going there today.
Another way to improve reporting in Visual Studio is adding /VERBOSE to the command line options in the linker section of the project configuration dialog widget. Be prepared for a ALOT of output.
Remediation
Back in the day, it used to be “RTFM” (Read The Effen Manual). These days, it’s “Google it.” While both man pages and google provide an enormous amount of information, digging out anything that can be put into immediate action is time consuming. The difficulty stems from the incapability of search engines to recognize fundamentally redundant results, from programmers (inexperienced or otherwise) not taking the time to learn the necessary rudiments of linker theory and technology to understand what the linker is telling them, from programmers that implemented the linker not taking the time to adequately document linker behavior, and from inadequate documentation of the errors themselves. Documentation of linker errors commonly resembles “unresolved symbol means the linker could not resolve the symbol.” For the inexperienced, this is a meaningless tautology. For the experienced, it’s simply redundant.
So how to proceed?
Let’s consider the MS Visual Studio case, since that’s what I am working on right. Examine the following message:
1>rwbearchD.lib(rs_actiondrawstairsuleft.obj) : error LNK2001: unresolved external symbol "public: virtual struct QMetaObject const * __thiscall RS_ActionDrawStairsULeft::metaObject(void)const " (?metaObject@RS_ActionDrawStairsULeft@@UBEPBUQMetaObject@@XZ)
In this particular case, the missing function is the void argument metaObject member of the RS_ActionDrawStairsULeft class.
(?metaObject@RS_ActionDrawStairsULeft@@UBEPBUQMetaObject@@XZ) is the compiler’s mangled name. Finding information on Microsoft’s proprietary name mangling is difficult, but some diligent searching turns up the following interpretation:
- (
- ? Prefix indicating mangled name following.
- metaObject@RS_ActionDrawStairsULeft the
metaObjectmember (method) of theRS_ActionDrawStairsULeftclass. - @@
- UBEPB
- U public virtual
- BE __thiscall calling convention, see note above.
- PBU returns pointer to struct (?)
The trailing (?)’s are mine, and indicate a best guess based on comparison between published information that has been reverse engineered, and the output of the linker error itself. (The Wordpress HTML editor is overriding my formatting of the sublist under UBEPBU, which is infuriating.)
In this particular case, the offending method was supposed to be auto-generated by the Qt meta-object compiler (moc). The project file (.vcproj) generated by the Qt integration tool “somehow ” missed the generated files, whence the linker could not find the appropriate methods.
Some useful links
- Dan Kegel has an extremely useful though possibly dated page on Microsoft name mangling.
- The Wikipedia article on Microsoft name mangling appears more up-to-date, although it is clearly incomplete and has been flagged as requiring clean up.
- Wikipedia also has a general article on name mangling which is quite informative.
- Microsoft’s dumpbin utility is extremely useful for dealing with decorations. Among several options, the decorated (mangled) names are emitted as part of the output from the executable or library given as input to dumpbin. The dumpbinGui web page has number of good links for digging further into the structure of executable code. Some of links (Microsoft’s) are dead, but the link names themselves provide hints for expanding search terms.
- Leor Zolman’s STL error filter, not quite on topic here, but a useful link for jumping into more general problems with compiling.
- Another class of linking errors results from linking with the incorrect Microsoft runtime library. A good overview, probably a little out of date, is currently here.
Was This Article Helpful To You?
If you did NOT find what you were looking for in this article, please leave a comment. I’ll update as necessary to keep the information accurate, useful and current.
[Published: May 25, 2008]
[Updated: Jan. 22, 2009]









{ 1 comment… read it below or add one }
The book would have been Linkers and Loaders by John Levine (also author of the O’Reilly book on Lex and Yacc and long-time moderator of the comp.compilers.moderated newsgroup. There really is only the one book on the topic (to my knowledge), which is a pity.