I am getting this single error when I am linking my project,
COMMUNICATION.obj : fatal error LNK1179: invalid or corrupt file: duplicate COMDAT '_IID_IXMLDOMImplementation'
What is the source of the problem?
This is a tricky one.
The issue is that the symbol(s)-generated is too-long, and an ambiguity exists:
//...
void MyVeryLongFunctionNameUnique_0(void);
void MyVeryLongFunctionNameUnique_1(void);
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// (example max-symbol-length-seen-by-linker)
In this case, the linker "sees" these two functions as the "same", because the part that makes them "unique" is longer-than-the-max-symbol length.
This can happen in at least three cases:
*.obj
, and it chokes the linker.Depending on the issue (above), you can "increase" your symbol-length (by limiting-your-decrease-of-symbol-length), or fix your code to make it valid (unambiguous) C++.
This error is (minimally) described by Microsoft at:
NOTE: This max-symbol-length can be set with the /H
option, see: http://msdn.microsoft.com/en-us/library/bc2y4ddf(v=vs.90).aspx
/H
is used on your command-line. If it is, delete it (do not specify max-symbol-length, it will default to 2,047
, the /H
can only DECREASE this length, not increase it).However, you probably triggered it through the /Gy
option (function-level-linking), which was probably implied through one of /Z7
, /Zi
, or /ZI
: http://msdn.microsoft.com/en-us/library/958x11bc(v=vs.90).aspx
One MSDN thread that talks about this issue is:
This thread suggests that it's possible to trigger this issue with "invalid-C++-code-that-compiles" (you get your *.obj
), but that invalid-*.obj
chokes the linker (this example attempts to use main
as both a function and as a template):
===[UPDATE]===
I should have said this before, because I suspected, but I now have more information: It might not be your fault, there seems to be an issue in the compiler and/or linker that triggers this error. This is despite the fact that the only common denominator in all your failed relationships is you.
Recall that the "above-list" applies (it MIGHT be your fault). However, in the case where, "it's not your fault", here's the current-running-list (I'm confident this list is NOT complete).
*.ilk
file (intermediate-link-file). Delete it and rebuild./INCREMENTAL
turned on for linking, but somehow that incremental-linking is not working for your project, so you should turn it off and rebuild (Project-Properties=>Configuration Properties=>Linker=>General=>Enable Incremental Linking
[set to "No" (/INCREMENTAL:NO
)]Project Proerties=>Configuration Properties=>Linker=>Optimization=>Enable COMDAT Folding
, set to "Remove Redundant COMDATs (/OPT:ICF
)Here's an interesting thread from a guy who sometimes can link, and sometimes not, by commenting in/out a couple lines of code. It's not the code that is the problem -- he just cannot link consistently, and it looks like the compiler and/or linker has an internal problem under some obscure use case:
Other observations from a non-trivial web search:
template<>
use===[PETITION TO THE GOOD PEOPLE OF THE WORLD]===
If you have other observations on this error, please list them below (as other answers, or as comments below this answer). I have a similar problem, and it's not my fault, and none of these work-arounds worked for me (although they did appear to work for others in their projects in some cases).
I'm adding a bounty because this is driving me nuts.
===[UPDATE+2]===
(sigh), Here's more things to try (which apparently work for others, but did not work for me):
this guy changed his compile settings, and it worked (from thread at http://forums.codeguru.com/showthread.php?249603.html):
Project->Settings->C++ tab, Debug cathegory: Inline function expansion
: change from 'None
' to 'Only _inline
'.
the above thread references another thread where the had to re-install MSVC
it is possibly related to linking modules with "subtle-differences" in possibly-incompatible compiler and/or link switches. Check that all the "contributing libs" are built with the exact same switches
Here's some more symptoms/observations on this error/bug:
Status: No joy.
===[UPDATE+3 : LINK SUCCESS]===
Super-wacky-makes-no-sense fix to successfully link discovered!
This is a variation on (above), where you "fiddle-with-the-code-until-the-compiler-and/or-linker-behaves". NOT GOOD that one might need to do this.
Specific single linker-error (LNK1179
) was for 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);
}
THE FIX:
MyMainBody<>()
from a "template<>
" to an explicit function, LINK SUCCESS.THIS FIX SUX, as I need the EXACT-SAME-CODE for other types in other utilities, and the MyMainBody<>()
implementation is non-trivial (but mostly simple) instantiations-and-setups that must be done in a specific way, in a specific order.
But hey, it's a temporary work-around for now: Confirmed on MSVC2008 and MSVC2010 compilers (same LNK1179
error for each, successful link on each after applying the work-around).
THIS IS A COMPILER AND/OR LINKER ERROR, as the code is "simple/proper-C++" (not even C++11).
So, I'm happy (that I got a link after suffering full-time for 2+weeks). But, disappointed (that the compiler and/or linker has a STUPID GLARING PROBLEM with linking a SIMPLE TEMPLATE<> in this use-case that I couldn't figure out how to address).
FURTHER, the "Bounty Ended", but nobody else wanted to take this on (no other answers?), so looks like "+100" goes to nobody. (heavy-sigh)
This question has a lot of answers but none of them quite capture what was happening in my codebase, and what I suspect the OP was seeing back in 2012 when this question was asked.
The COMDAT error on an IID_*
type is easy to accidentally reproduce by using the #import
directive with both the rename_namespace
and named_guids
attributes.
If two #import
ed type libraries contain the same interface, as is likely the case for OP's IXMLDOMImplementation
, then the generated .tlh
files will declare IID_IXMLDOMImplementation
in both namespaces, leading to the duplicate.
For example, the code generated for:
#import <foo.tlb> rename_namespace("FOO") named_guids;
#import <bar.tlb> rename_namespace("BAR") named_guids;
...could be simplified into something like this:
namespace FOO {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
namespace BAR {
extern "C" __declspec(selectany) const GUID IID_IFOOBAR = {0};
}
Here's a simple RexTester reproduction of the problem: https://rextester.com/OLAC10112
The named_guids
attribute causes the IID_*
to be generated and the rename_namespace
attribute wraps it in the namespace.
Unfortunately, in this case, extern "C"
does not seem to work as expected when it appears inside a C++ namespace. This causes the compiler to generate multiple definitions for IID_FOOBAR
in the same .obj
file.
DUMPBIN /SYMBOLS
or a hex editor confirms the duplicate symbols.
The linker sees these multiple definitions and issues a duplicate COMDAT
diagnostic.
Knowing that rename_namespace
doesn't play well with named_guids
, the obvious solution is to simply not use them together. It's probably easiest to remove the named_guids
attribute and instead use the _uuidof()
operator.
After removing named_guids
from #import
directives and touching up the code, replacing all uses of FOO::IID_IFooBar
with _uuidof(FOO::IFooBar)
, my COM-heavy codebase is back to building again.
This issue is reported as a bug in some specific versions of Visual Studio 2017. Try patching 15.9.1 or later to fix this issue
Reported Issue in VS 15.8 Preview 4
Resolved patchs in VS 15.9 Preview 2
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With