連結器工具警告 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
,且相關聯的.obj
檔案是在 之前pch.obj
處理,連結器將會/Yc
擲回LNK4221。
此錯誤的常見原因是,當兩個來源檔案指定選項 /Yc
[建立先行編譯頭檔] 與 [先行編譯頭檔] 字段中指定的相同頭文件名稱時。 此問題的常見原因會處理 stdafx.h
,因為根據預設, stdafx.cpp
會包含 stdafx.h
且不會新增任何新的符號。 如果另一個原始程式檔包含 stdafx.h
,且相關聯的.obj
檔案是在 之前stdafx.obj
處理,連結器將會/Yc
擲回LNK4221。
解決此問題的其中一種方法是確保針對每個先行編譯標頭檔,只有一個原始程式檔包含它與 /Yc
。 所有其他原始程式檔都必須使用先行編譯標頭。 如需如何變更此設定的詳細資訊,請參閱/Yu
(使用先行編譯頭檔)。