链接器工具警告 LNK4221
此对象文件未定义任何之前未定义的公共符号,因此任何耗用此库的链接操作都不会使用此文件
请思考以下两个代码片段:a.cpp
// a.cpp
#include <atlbase.h>
以及 b.cpp
:
// b.cpp
#include <atlbase.h>
int function()
{
return 0;
}
若要编译文件并创建两个对象文件,请在命令提示符处运行 cl /c a.cpp b.cpp
。 如果通过运行 link /lib /out:test.lib a.obj b.obj
链接对象文件,将收到 LNK4221 警告。 如果通过运行 link /lib /out:test.lib b.obj a.obj
链接对象,将不会收到警告。
第二个场景中没有发出警告,因为链接器以后进先出 (LIFO) 方式运行。 在第一个场景中,b.obj
在 a.obj
之前处理,并且 a.obj
没有要添加的新符号。 通过指示链接器先处理 a.obj
,可以避免发出警告。
此错误的一个常见原因是,两个源文件指定选项 /Yc
(创建预编译头文件),其头文件名与“预编译标头”字段中指定的头文件名相同。 此问题的一个常见原因涉及 pch.h
,因为默认情况下,pch.cpp
包括 pch.h
且不会添加新符号。 如果另一个源文件包含 pch.h
和 /Yc
,并且在 pch.obj
之前处理关联的 .obj
文件,则链接器将引发 LNK4221。
此错误的一个常见原因是,两个源文件指定选项 /Yc
(创建预编译头文件),其头文件名与“预编译标头”字段中指定的头文件名相同。 此问题的一个常见原因涉及 stdafx.h
,因为默认情况下,stdafx.cpp
包括 stdafx.h
且不会添加新符号。 如果另一个源文件包含 stdafx.h
和 /Yc
,并且在 stdafx.obj
之前处理关联的 .obj
文件,则链接器将引发 LNK4221。
解决此问题的一种方法是确保对于每个预编译标头而言,只有一个源文件包含它和 /Yc
。 所有其他源文件都必须使用预编译标头。 有关如何更改此设置的详细信息,请参阅 /Yu
(使用预编译头文件)。