locked
lnk2022 trying to compile debug with _HAS_ITERATOR_DEBUGGING=0 RRS feed

  • Question

  • I'm trying to compile in debug with:

    _HAS_ITERATOR_DEBUGGING=0

    _SECURE_SCL=0

    (for performance reasons while debugging our software)

    I get the following linker errors:

     

    Warning               1              warning LNK4068: /MACHINE not specified; defaulting to X86                C:\DotNet\framework\TypeLibImports\LINK     TypeLibImports

    Error      2              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<char,std::char_traits<char>,std::allocator<char> >): (0x0200004e).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      3              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >): (0x02000075).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      4              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000091).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      5              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_const_iterator<char,std::char_traits<char>,std::allocator<char> >): (0x02000092).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      6              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000097).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      7              error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<wchar_t,std::allocator<wchar_t> >): (0x02000099).                C:\DotNet\framework\oqkern\MSVCMRTD.lib(locale0_implib.obj)         oqkern

    Error      8              error LNK1255: link failed because of metadata errors    C:\DotNet\framework\oqkern\LINK      oqkern

    I don't have /Zp, and I've tried with /MDd and just /MD

     

    Any ideas?

     

    Monday, January 10, 2011 4:27 PM

Answers

  • If you Google/Bing for comparisons between .NET managed containers and STL containers, experiments seem to show that the .NET managed containers are surprisingly efficient, and indeed outperform the STL equivalents. Here is one reference, but I've seen others. Obviously in debug mode, the STL is extremely slowed by the checked iterators, so it is a good reason to move on to .NET managed containers if this is important to your project.

    Note, however, that in Visual Studio 2010, substantial improvements have been made to the STL primarily because of the implementation of R-value references, so I can't comment on relative performance with the VS 2010 implementation. However, it simply strikes me that if you are writing managed code (/clr), that using managed containers should be the first tool to consider, since it is less likely you will need to marshal elements back and forth between the unmanaged and managed world.

    Incidentally, I'm not exactly certain why you want to improve the debug performance, since debug performance has almost no bearing on the performance of the release version.

     

    • Marked as answer by lucy-liu Thursday, January 20, 2011 10:18 AM
    Tuesday, January 11, 2011 9:13 PM

All replies

  •  Any ideas?
    Most likely you are linking modules where some of been built with _HAS_ITERATOR_DEBUGGING=0 SECURE_SCL=0 but at least one has not. Any DLL's you have written also have to be compiled in the same manner.
    Monday, January 10, 2011 4:48 PM
  • You're compiling with /clr . For technical reasons, we can't support modifying _SECURE_SCL/_HAS_ITERATOR_DEBUGGING under /clr anymore.
    Monday, January 10, 2011 10:49 PM
  • Thanks for the responses.

    I was attempting this in order to improve debugging performance.  Is it possible that this is a major culprit?  Is it impossible to disable _HAS_ITERATOR_DEBUGGING under /clr now? Are there any other ideas for debugging more quickly?  

    I'm looking at times of:

    12 seconds release

    35 seconds debug (not under debugger)

    60 seconds (under the debugger)


     

    Tuesday, January 11, 2011 2:59 PM
  • Since you are coding using /clr, you should be using managed containers, not the STL, if you really want to speed things up.

    Tuesday, January 11, 2011 5:23 PM
  • is it because of how the STL types are compiled in the crt?

    If so, maybe it's possible to compile a debug crt onesself with iterator debugging disabled as a workaround?

    Tuesday, January 11, 2011 6:43 PM
  • If you Google/Bing for comparisons between .NET managed containers and STL containers, experiments seem to show that the .NET managed containers are surprisingly efficient, and indeed outperform the STL equivalents. Here is one reference, but I've seen others. Obviously in debug mode, the STL is extremely slowed by the checked iterators, so it is a good reason to move on to .NET managed containers if this is important to your project.

    Note, however, that in Visual Studio 2010, substantial improvements have been made to the STL primarily because of the implementation of R-value references, so I can't comment on relative performance with the VS 2010 implementation. However, it simply strikes me that if you are writing managed code (/clr), that using managed containers should be the first tool to consider, since it is less likely you will need to marshal elements back and forth between the unmanaged and managed world.

    Incidentally, I'm not exactly certain why you want to improve the debug performance, since debug performance has almost no bearing on the performance of the release version.

     

    • Marked as answer by lucy-liu Thursday, January 20, 2011 10:18 AM
    Tuesday, January 11, 2011 9:13 PM
  • I work with Derek and thought I would address the last question - why do we care about debug performance?  Basically we have several developers that spend 90% of their time working in debug.  Debugging performance has become a huge productivity problem.  Profiling is showing the STL debug code as being a major culprit.
    Thursday, January 13, 2011 8:26 PM
  • Basically we have several developers that spend 90% of their time working in debug.  Debugging performance has become a huge productivity problem. 

    I understand.

    Unfortunately, I don't see a way around this issue, other than to move away from STL containers in favour of managed containers. You'll have to decide if the impact of this effort is worth it. 

    Thursday, January 13, 2011 8:38 PM
  • Thanks Brian.  I think we are stuck with STL since we have both managed and unmanaged (most) code using our collections.

    I just came across this elsewhere, I assume it has the same /clr limitations Stephen mentions above:  “The new _ITERATOR_DEBUG_LEVEL macro invokes debugging support for iterators. Use this macro instead of the older _SECURE_SCL and _HAS_ITERATOR_DEBUGGING macros.”

    Thursday, January 13, 2011 8:52 PM
  • Stephen - I don't suppose there is any more technical information as to what the "technical reasons" are or if there are alternatives/workarounds?  Just looking for options.  Thanks.
    Thursday, January 13, 2011 9:14 PM
  • It's complicated, and even I don't fully understand everything that's going on (mostly because I don't know very much about managed code).  The underlying problem is that _ITERATOR_DEBUG_LEVEL affects the representations of STL containers, and C++ (both native and especially managed) really hates it when code can't agree on the representation of an object.  When _SECURE_SCL/_HAS_ITERATOR_DEBUGGING were added in VC8, we should have created 5 variants of the CRT/STL binaries (including DLLs).  Unfortunately we didn't (this was before my time, otherwise I would have spoken up), and having only debug and release DLLs causes headaches.  We suffered from longstanding problems in VC8/9 until we overhauled how this worked in VC10.  During VC10 we untangled the worst of the problems by making std::string header-only.  With invasive surgery we were able to get native code working correctly in every case except one very obscure one that nobody has noticed or complained about yet.  (We now have 5 static libs, which solves the case of static linking absolutely 100% perfectly, but still only 2 DLLs.)  But managed code is structured differently, and the tricks that work in native don't work for it.  As a result, customizing _ITERATOR_DEBUG_LEVEL basically doesn't work under /clr[:pure].  Very few customers have encountered this (you're one of the first) because we changed the release mode default to IDL=0 (which everyone wants), and few people want to modify debug mode's default of IDL=2.

    Have you considered making your "debug build" compile in release mode with no optimizations?  Release mode versus debug mode affects what CRT/STL/etc. you link to (and whether you can effectively debug into them) and as a side effect affects your IDL default, but it's not inherently tied to whether your own code is compiled with optimizations or not, and that's what affects the debuggability of your own code.  The IDE pairs release mode with optimizations and debug mode without optimizations, but there's no fundamental reason linking the two.

    Thursday, January 13, 2011 10:55 PM
  • So I take it that the move of std::string to be header only (no lib dependencies right?) would explain these types of linker errors:

    Warning 102 warning LNK4049: locally defined symbol ?size@?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@QBEIXZ (public: unsigned int __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::size(void)const ) imported E:\app\myfoo.lib(operations.obj)

    Which means it's both imported and exported at the same time. (I"ll have to get my vendor to give me myfoo.lib compiled with vc 10.0)

    Thursday, April 7, 2011 8:44 AM
  • Stephan - is this fixed in VS2013?  This is pretty much a blocking issue for us (in VS2010)..

    Thanks!

    Tuesday, September 23, 2014 4:45 PM