Note: LNK2001 does not mean that the linker really needs to link related symbols

Source: Internet
Author: User

Environment: VS2008 As we all know, the linker ignores symbols that are not used when generating executable programs. But yesterday there was a link problem that seemed to be inconsistent with this basic strategy. First look at the structure of a static link library:
                lib                 |      | ---------------------|     a.cpp                 b.cpp      |                     |  | -------|           | -----------| fun1     fun2       fun3         fun4  |       ↑___________|   ↓getmodulefilenameex (psapi.lib)

There are only two dependencies in this library: Fun3 in B.cpp relies on fun1 in PSAPI.lib in A.cpp fun2,a.cpp. I used fun4 in an app, and there was nothing else, and obviously I didn't need to link psapi.lib, according to the strategy mentioned at the beginning. However, this is not the case, the linker has prompted the error: LNK2001: unresolved external symbols [email protected] have been repeatedly tested to confirm that FUN1 relies on Getmodulefilenameex caused the link error. This seems incredible, FUN4 does not have any dependencies on fun1, why does the linker report an error? In my experience, the linker will use this strategy for sure, and most likely, there is a cognitive error. So I decided to verify that the validation here is divided into two parts: first, does the linker require parsing a symbol to imply that the linker needs to include the code of the relevant symbol in the generated PE file? When encountering a LNK2001 error, our first impression is that the linker needs to include this symbol in the generated program, which is: 1. If the symbol is in a static library, then the code related to the symbol is included in the PE file; 2. If the symbol is in a dynamic library, then the symbol needs to be recorded in the import table so that the relevant dynamic library will be loaded into the process and address mapped at the start of the program, but the linker is suggesting a LNK2001 error in a function that is obviously not dependent, which makes me feel The suspicion arises: perhaps the linker parsing a symbol does not imply that it will contain the relevant code in the generated executable program. With a simple contrast test you can tell the result:
#include <windows.h>#include<psapi.h>#pragmaComment (lib, "PSAPI.lib")voidFun_infile_unuse () {TCHAR Buf[max_path]; Getmodulefilenameex (GetCurrentProcess (), NULL, buf, MAX_PATH);}voidFun_infile_use () {Outputdebugstringa ("fun_infile_use\r\n");}int_tmain (intARGC, _tchar*argv[])    {Fun_infile_use (); //fun_infile_unuse ();GetChar (); return 0;}

First, in this program, whether or not to call the Fun_infile_unuse function, #pragma comment (lib, "PSAPI.lib") are indispensable, otherwise the linker will prompt LINK2001 error. However, to call and do not call Fun_infile_unuse two cases compiled two copies of the program, with LOADPE to view the import table of the PE file, you can see: Only call the Fun_infile_ There are psapi.dll entries in the Export table of the Unuse program, but not in the export table of the other program. Run two copies of the program, use Process Explorer to view the list of libraries they have loaded, as well as see: There is no call to Fun_infile_unuse the program, run will not load Psapi.dll. --The picture is not posted, interested in their own verification. Obviously, if a Psapi.dll import table entry does not exist in a program that does not call Fun_infile_unuse, it should also not contain fun_in_fun_unuse code in the program. This confirms my suspicion. That is, the linker needs to parse a symbol, not that it really needs a "link" symbol. The linker does follow the "ignore unused symbols" principle when it actually links symbol generators. But that's not all, and when we get this conclusion, it means that the linker does not traverse through the dependency on the call when it looks for the symbol. So, what does the linker do with the relationships that traverse the symbols? This is the next question. Second, the linker based on what kind of relationship to determine the "resolution" of the symbol range? I'm not going to make a rigorous inference to this question, just using a few tests to compare and verify one of my guesses. These test cases are:
1 .        App           |         |---------|---------| fun1     fun2       |         ↑_________| ↓getmodulefilenameex (psapi.lib)

2 .        App           | |-----------------| other.cpp        |                 | |            | ---------| fun1        fun2       |            ↑_________| ↓getmodulefilenameex (psapi.lib)

3 .   Lib            app      |              |     a.cpp          main.cpp      |              |  | -------|          | fun1     fun2       main  |       ↑__________|   ↓getmodulefilenameex (psapi.lib)

4 .              Lib                         app                 |                           |      | ---------------------|                |     a.cpp                 b.cpp            main.cpp      | | | |  -------|           | -----------|          | fun1     fun2       fun3         fun4       main  |                               ↑__________|   ↓getmodulefilenameex (psapi.lib)

5 .              Lib                         app                 |                           |      | ---------------------|                |     a.cpp                 b.cpp            main.cpp      | | | |  -------|           | -----------|          | fun1     fun2       fun3         fun4       main  |       ↑___________|           ↑__________|   ↓getmodulefilenameex (psapi.lib)

The test results for the above-mentioned use cases are as follows: Use cases (number): 1 2 3 4 5 whether LINK2001: Yes Yes is it note: in my To do the real test, but also to the namespace of the inclusion of the test, the results found no impact, from the meaning of the namespace, it should not have an impact, so the relevant tests are not listed in. As we all know, the static link library is made up of a set of obj, and obj corresponds to CPP one by one. So here's a guess: the linker searches for symbols based on the invocation relationship, but in the case of obj as node units. 1. For all CPP (obj) within project, the linker requires that all of the symbols used are resolved. 2. For an external library, if a symbol is used, the position of the symbol is located in obj, and all symbols in that obj are required to be parsed. And so on Finish. The second part is not rigorous testing, nor intend to further test, because the need to confirm is only the first part. If you are interested in the second part of the content, then I am very much looking forward to seeing your conclusion: [email protected]

Note: LNK2001 does not mean that the linker really needs to link related symbols

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.