dotNoted

Icon

Observations of .Net development in the wild

On using namespace std, dealing with “Microsoft.VS80.DebugCRT could not be found” and resolving the LNK2022 VC++ linker error when converting from VS2005 to VS2008

This one was odd.

I had a VS2005 C++/CLI project, and in a recent iteration, had added some logging code using the standard library’s streams package. One of the things I noticed early, by way of the program absolutely failing to get off the ground and writing an SxS exception to the system event log, was that including the standard library in the default Debug configuration resulted in the program acquiring a dependency on the Debug MSVCRT DLLs. I had been using the release DLLs (via compiler switch /MD) since I didn’t want the hassle of having to make sure the non-redistributed Debug DLLs were on the build server and test machines, etc. Having weighed whether it was worth it for getting to include std, I decided it was, and made it a requirement to have the 4 required files (the 3 runtime DLLs and one manifest file) in the target dir at the build server and test machines. That solved the SxS error (Dependent Assembly Microsoft.VC80.DebugCRT could not be found… Last Error was “The referenced assembly is not installed on your system”).

Then I switched over to VS2008. I figured it would be pretty seamless, since nothing really changed. However, I kept getting numerous LNK2022 error from the linker, like – “error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.domain_error)”. There was obviously something wrong with including the standard library. If I commented out “using namespace std;” and all references to it (there were only a few), the program compiled. The linker was having problems with MSVCMRT.lib – the managed portion of the CRT. How could I change it, since VC++ picks it based on its version? The answer was to change the compile switch from /MD to /MDd for the project in the Debug configuration. Now the layout of the std types is the same, and the linker doesn’t complain.

Why hadn’t I needed to do this when the project was in VS2005? Perhaps the layout of debug and redist types in VS2005 were the same, or there was some special mode that VS2005 entered when it detected this usage pattern, and which is lost in the conversion.

Filed under: C++ / CLI