这是一个棘手的问题。
问题是生成的符号太长,存在歧义:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
在这种情况下,链接器将这两个函数“视为”“相同”,因为使它们“唯一”的部分比最大符号长度长。
这可能发生在至少三种情况:
- 您的符号名称“太长”而不能被认为是链接器独有的,但对于编译器来说可能没问题(例如当您从许多嵌套模板中展开时)
- 您做了一些无效 C++ 的“诡计”,它通过了编译器,但您现在有一个无效的
*.obj,它阻塞了链接器。
- 您指定了重复的“未命名”类/结构,链接器无法解析它们。
-
===[UPDATE]===,这不是你的错,这是编译器和/或链接器的内部问题(请参阅下文了解可能的解决方法)。
根据问题(如上),您可以“增加”符号长度(通过限制符号长度的减少),或修复代码以使其有效(明确)C++。
Microsoft 在以下位置(最少)描述了此错误:
注意:此最大符号长度可以使用/H 选项设置,请参阅:http://msdn.microsoft.com/en-us/library/bc2y4ddf(v=vs.90).aspx
-
建议: 检查您的命令行上是否使用了
/H。如果是,删除它(不指定max-symbol-length,默认为2,047,/H只能DECREASE这个长度,不能增加它)。
但是,您可能通过/Gy 选项(函数级链接)触发了它,这可能是通过/Z7、/Zi 或/ZI 之一隐含的:http://msdn.microsoft.com/en-us/library/958x11bc(v=vs.90).aspx
讨论此问题的一个 MSDN 线程是:
这个线程表明可以使用“invalid-C++-code-that-compiles”触发这个问题(你得到你的*.obj),但是那个invalid-*.obj会阻塞链接器(这个例子试图使用main 既作为函数又作为模板):
===[更新]===
我之前应该说这个,因为我怀疑,但我现在有更多信息:这可能不是你的错,编译器和/或链接器中似乎存在触发此错误的问题。尽管事实上所有失败的关系中唯一的共同点就是你自己。
回想一下“上面的列表”适用(这可能是你的错)。但是,在“这不是你的错”的情况下,这里是当前运行列表(我相信这个列表不完整)。
-
*.ilk 文件(中间链接文件)中存在内部错误/损坏。删除并重建。
- 您已为链接打开了
/INCREMENTAL,但不知何故增量链接不适用于您的项目,因此您应该将其关闭并重建 (Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking [设置为“否”(/INCREMENTAL:NO)]
- 在您的使用中,“COMDAT 折叠”的“优化”存在问题。您可以通过转到
Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding 来“删除冗余 COMDATs”,设置为“删除冗余 COMDATs (/OPT:ICF)
这是一个有趣的线程,来自一个有时可以链接,有时不能,通过注释/注释几行代码。问题不是代码——他只是无法一致地链接,而且看起来编译器和/或链接器在一些晦涩的用例下存在内部问题:
来自非平凡网络搜索的其他观察结果:
- 这个问题似乎并不罕见
- 它似乎与某种形式的
template<> 使用有关
- 其他人似乎在“发布”版本中看到此问题,而“调试”版本没有此问题(但在许多情况下,“调试”版本中也有此问题)
- 如果链接在一台机器上“失败”,它可能在另一台构建机器上“成功”(不知道为什么,“干净构建”似乎没有效果)
- 如果您注释/注释掉特别重要的几行代码,并完成构建,并继续这样做,直到所有代码再次取消注释,您的链接可能会成功(这似乎是可重复的)
- 如果您在使用 MSVC2008 时遇到此错误,并且您将代码移植到 MSVC2010,您仍然会收到此错误
===[致全世界好人的请愿书]===
如果您对此错误有其他意见,请在下面列出(作为其他答案,或作为此答案下方的 cmets)。我有一个类似的问题,这不是我的错,而且这些变通方法都不适合我(尽管在某些情况下它们似乎确实适用于其他人的项目)。
我正在添加赏金,因为这让我发疯了。
===[更新+2]===
(叹气),还有更多可以尝试的方法(显然对其他人有用,但对我无效):
-
这家伙改变了他的编译设置,并且它起作用了(来自http://forums.codeguru.com/showthread.php?249603.html的线程):
Project->Settings->C++ tab, Debug cathegory: Inline function expansion:从“None”更改为“Only _inline”。
上面的线程引用了另一个必须重新安装 MSVC 的线程
这可能与在可能不兼容的编译器和/或链接开关中链接具有“细微差异”的模块有关。检查所有“贡献库”是否使用完全相同的开关构建
以下是有关此错误/错误的更多症状/观察结果:
- 上述问题的列表仍然适用
- 问题似乎在 MSVC2005 中“开始出现”,并且在 MSVC2008 和 MSVC2010 中继续出现相同的行为(将代码移植到较新的编译器后仍然会出现错误)
- 重启 IDE,重启机器似乎对任何人都不起作用
- 一个人说明确的“清理”然后重新编译对他有用,但许多其他人说这对他们不起作用
- 通常与“增量链接”相关(例如,将其关闭)
状态:不开心。
===[更新+3:链接成功]===
Super-wacky-makes-no-sense 修复成功发现链接!
这是(上图)的一种变体,您可以“摆弄代码直到编译器和/或链接器行为”。可能需要这样做并不好。
特定的单个链接器错误 (LNK1179) 用于 MyMainBody<>():
#include "MyClassA.hpp"
#include "MyClassB.hpp"
#include "MyClassC.hpp"
#include "MyClassD.hpp"
#include "MyMainBody.hpp"
int main(int argc, char* argv[])
{
// Use a function template for the "main-body",
// implementation is "mostly-simple", instantiates
// some local "MyClass" instances, they reference
// each other, and do some initialization,
// (~50 lines of code)
//
// !!! LNK1179 for `MyMainBody<>()`, mangled name is ~236 chars
//
return MyMainBody<MyClassA,MyClassB,MyClassC,MyClassD>(argc,argv);
}
修复:
- 将
MyMainBody<>()从“template<>”转换为显式函数,LINK SUCCESS。
这个 FIX SUX,因为我需要 EXACT-SAME-CODE 用于其他实用程序中的其他类型,并且 MyMainBody<>() 实现是不平凡的(但大多是简单的)实例化和设置这必须以特定的方式,以特定的顺序完成。
但是,嘿,现在这是一个临时解决方法:在 MSVC2008 和 MSVC2010 编译器上得到确认(每个都相同的 LNK1179 错误,在应用解决方法后每个都成功链接)。
这是编译器和/或链接器错误,因为代码是“简单/正确的 C++”(甚至不是 C++11)。
所以,我很高兴(在全职工作 2 周以上后,我得到了一个链接)。但是,很失望(编译器和/或链接器有一个愚蠢的问题,在这个用例中链接一个简单的模板,我无法弄清楚如何解决)。
进一步,“赏金结束”,但没有其他人愿意接受这个(没有其他答案?),所以看起来像“+100”没有人。 (沉重的叹息)