C++ visual studio libraries - c++

Is there any way to make static libraries built in Microsoft Visual Studio independent from used CRT (with debug support / without it)?
I mean like, for simple C library it is possible to generate code using gcc and then use the same static library in visual studio. The resulting library.a file is completely independent from /MT or /MDd switches and does not result in warning / linking errors.
Comparing to Visual Studio default behaviour, you would have to build two versions of the same library - for Debug / Release modes independently. If you try to use the Release version in Debug configuration or vice-versa, this results in ugly warnings (warning LNK4098: defaultlib "LIBCMT" ...), but sometimes does not compile due to different runtimes?
Is there any way to avoid this? Or probably I'm doing something wrong?

To make a lib that will link in regardless of runtime selection it is necessary to use two switches:
/MT to build against the basic release runtime, /Zl to omit the default library names.
Building against the dll runtimes will cause the compiler to decorate all the runtime symbols with __imp_ (so, for example, it will try and link against __imp__fread rather than _fread). So you have to choose one of the static runtimes.
The compiler does an implicit default library pragma, depending on the lib selected:
#pragma comment(lib,"libcmtd.lib")
is how it looks in code. The /Zl causes the compiler to omit all these directives - (implicit and explicit) from the resulting .obj (and hence .lib) file. So the result will should link cleanly without causing default library conflicts.

No. The object files for the default release and debug configurations are completely different -- debug object binaries are relocatable machine executable object code, release object binaries are simply an intermediate representation of the original code. That is, the backend is in the linker for release builds, but is in the compiler for debug builds. Putting the backend is in the Linker allows the compiler back end to make more intelligent decisions with respect to optimization of your program, at the expense of longer compilation times.

Is there a problem with distributing 2 versions of the library? I don't claim to speak for everybody, but I always like to have a debug version, compiled against the static debug libs, with asserts and extra checking compiled in. (Symbols are good, too, of course!) The asserts and checks are helpful, the stack traces are usually better when the thing crashes in the library code, and it's often easier to read the disassembly.

Related

should I link to Debug or Release dll with same name?

I was working on a MS Visual Studio project and noticed that the Debug build was Linking to a Release library (DLL), when a Debug library with the same name was also available. I switched the path to Link the Debug library, and it seems to still work. Is there any way to know if my change was correct?
Additional Information:
Using the debug DLL triggers a small memory leak that wasn't triggered with the release DLL. Or possibly that is debug related cache data. That leak made me question if it was including the lib headers without _DEBUG somehow. Thus this question.
It is the preferred way to link Debug builds of your program with Debug version of external dynamic libraries as it guarantees that uniform Visual C++ runtime libraries will be used. Mixing libraries built in Debug and Release mode will result in both Debug and Release VC++ runtimes being linked and annoying linker warnings about multiple symbol definitions in conflicting Debug/Runtime libraries.
Sometimes it may be inevitable as i.e. only Release version of some external library may be available. Hence in VC++ there are linker settings allowing to ignore some specific libraries. So you may start checking in the Linker-Input settings of the Debug build if such ignores are already defined for existing conflicts. With some luck you might be able to remove them now.
If using the Debug version of some library breaks the whole program it might be an insight how to improve the whole system, it is that what a Debug build is for anyway.
Assuming that it is the right library (as in the same code compiled to a different configuration), you are right to link to the debug dll on your debug configuration (and should link to the release dll on your release configuration).
The differences tend to be related to the optimisation level (Debug is usually compiled without any optimisation at all) and any symbols that might be included to make it easier to develop with and maybe step into.

Mixing STL debug/release libraries

I'm aware that mixing debug and release libraries that pass STL containers to each other causes big problems. But what exactly in 'debug' or 'release' causes this?
I have a QT project that gets built as 'release', but it has /DEBUG added to the compiler flags.
If I build another QT project under 'debug' (which also has the /DEBUG flag), are they compatible?
Or is there an optimization flag or some other flag that makes them incompatible?
Basically, is there a way I can look at the compilation line of the 2 libraries and see something that says "DON'T MIX THESE!"?
This is undefined behaviour, so it might work but more probably it will crash your app. It also depends on stl implementation, in debug version it might enable additional checks and allocate additional memory making data layout different in release modes. In the end this violates ODR rule (one definition rule) once again causing undefined behaviour.
I have a QT project that gets built as 'release', but it has /DEBUG added to the compiler flags. If I build another QT project under 'debug' (which also has the /DEBUG flag), are they compatible?
If your Release contains exactly the same compiler flags as Debug then I would say they are compatible.
Or is there an optimization flag or some other flag that makes them incompatible?
you should be able to see those flags, I dont think optimization flags should cause UB problems, its rather different macros used during compilation phase that cause ODR violation. Maybe there are optimization flags which changes alignment in structures...
Basically, is there a way I can look at the compilation line of the 2 libraries and see something that says "DON'T MIX THESE!"?
no idea here.
Why are you mixing differently build libraries in the first place? this is asking for trouble.
Not really. Concerning Visual C++'s STL implementation, there are data members of the containers corresponding to the iterator checking that is only compiled in if some preprocessor variables are set. These variables are default valued base on the NDEBUG preprocessor variable that is quasi standard for "no debug". But these could be also set directly from the command line, or from header files, or Visual Studio property pages, etc.
E.g.: all containers are derived from _Container_base, while that is a typedef depending on _ITERATOR_DEBUG_LEVEL. The different _Container_base implementations have different memory layout, and that is what causes incompatibilities between the debug and release version.
The /DEBUG compiler flag tells the compiler whether to generate debug information or not, and might also affect default values for optimization settings, but I am not sure about that, and of course that is compiler dependent.
Just like there could be an STL implementation that does not depend on any preprocessor directives, and in that case it would not matter how you compile it, debug or release, the memory layout would be identical, and so it could be passed around between modules compiled the different ways.
Firstly the /DEBUG flag doesn't actually create a 'debug' build. It just tells the linker to generate debugging information and create a .pdb file along with the resulting binary.
As to the difference between the debug and release MSVC++ runtimes the issue is to do with the fact that different runtimes can have different sizes for the same object. e.g. in debug extra information might be placed in iterators to ensure their validity at run time. If code has been compiled against the release version of these structures then corruption is likely. Another issue would be if an object if allocated from the heap of one runtime and is attempted to be freed on the heap of another runtime.

Using debug/release versions DLL in C++

I am writing an C++ application that could be compiled under Linux (gcc 4.3) and Windows (MS VS08 Express).
My application uses third-party libraries,
On Linux , they are compiled as shared libraries, while
on Windows, there are two versions "Debug" and "Release".
I know that debug version provides extra support for debugging ( just like using -ggdb option in linux gcc, right? )
But I found that if my application is in debug version , the libraries must also be in debug version, otherwise the application will crash.
Why is there such a limit? It seems that there are no such limits in the linux world
Thank you very much!
The Debug configuration of your
program is compiled with full symbolic
debug information and no optimization.
Optimization complicates debugging,
because the relationship between
source code and generated instructions
is more complex.
The Release configuration of your
program contains no symbolic debug
information and is fully optimized.
Debug information can be generated in
PDB Files (C++) depending on the
compiler options used. Creating PDB
files can be very useful if you later
need to debug your release version.
Debug vs Release
It is also possible to debug your release build with the compiler flags.
Debugging Release Builds
Heap Layout - Guard Bytes to prevent overwriting
Compilation - Removing Assert/Debug Info
Pointer Support - Buffers around pointers to prevent seg faults
Optimization - Inline Functions
Common Problems When Creating Release Builds
To elaborate on Martin Tornwall. The various libraries linked when in Debug or Release
LIBCPMT.LIB, Multithreaded, static link, /MT, _MT
LIBCPMTD.LIB, Multithreaded, static link, /MTd, _DEBUG, _MT
CRT Libraries
Most likely, the Release and Debug versions are linked against different versions of the C++ Runtime library. Usually, a Debug build links against the "Multithreaded Debug DLL" runtime, whereas a Release build will generally link against "Multithreaded DLL". Loading DLLs whose runtime libraries are mismatched with that of the application will often lead to mysterious crashes.
You could try verifying that all your DLLs build against the same runtime library as your application, regardless of which configuration (Debug or Release) is active. Whether or not this is desirable is another question entirely.
The ability to choose which runtime library to link with enables the application developer to select the best feature set given her application's requirements. For example, a single-threaded application might incur performance penalties as a result of unnecessary thread synchronization if it is linked with a runtime library that is designed with thread safety in mind. Likewise, the consequences of linking a multi-threaded application against a single-threaded runtime could potentially be disastrous.
While I never intentionally link libraries that were built with different compiler settings, there isn't much point in doing so, I only know of the STL classes in the Dinkumware implementation (the one MSFT uses) to cause this problem.
They support a feature called 'iterator debugging' which is turned on by default in the Debug configuration. This adds members to the classes to aid the diagnostic code. Making them larger. This goes bad when you create the object in a chunk of code that was compiled with one setting and pass it to code that was compiled with the opposite setting. You can turn this off by setting the _HAS_ITERATOR_DEBUGGING macro to 0. Which is rather a major loss, the feature is excellent to diagnose mistakes in the way you use STL classes.
Passing objects or pointers between different libraries is always a problem if you don't carefully control the compile settings. Mixing and matching the CRT version and flavor gets you in trouble when you do so. This normally generates a warning from the linker, not sure what you did to not see it. There won't be one if the code lives in a DLL.

Should I compile with /MD or /MT?

In Visual Studio, there's the compile flags /MD and /MT which let you choose which kind of C runtime library you want.
I understand the difference in implementation, but I'm still not sure which one to use. What are the pros/cons?
One advantage to /MD that I've heard, is that this allows someone to update the runtime, (like maybe patch a security problem) and my app will benefit from this update. Although to me, this almost seems like a non-feature: I don't want people changing my runtime without allowing me to test against the new version!
Some things I am curious about:
How would this affect build times? (presumably /MT is a little slower?)
What are the other implications?
Which one do most people use?
By dynamically linking with /MD,
you are exposed to system updates (for good or ill),
your executable can be smaller (since it doesn't have the library embedded in it), and
I believe that at very least the code segment of a DLL is shared amongst all processes that are actively using it (reducing the total amount of RAM consumed).
I've also found that in practice, when working with statically-linked 3rd-party binary-only libraries that have been built with different runtime options, /MT in the main application tends to cause conflicts much more often than /MD (because you'll run into trouble if the C runtime is statically-linked multiple times, especially if they are different versions).
If you are using DLLs then you should go for the dynamically linked CRT (/MD).
If you use the dynamic CRT for your .exe and all .dlls then they will all share a single implementation of the CRT - which means they will all share a single CRT heap and memory allocated in one .exe/.dll can be freed in another.
If you use the static CRT for your .exe and all .dlls then they'll all get a seperate copy of the CRT - which means they'll all use their own CRT heap so memory must be freed in the same module in which it was allocated. You'll also suffer from code bloat (multiple copies of the CRT) and excess runtime overhead (each heap allocates memory from the OS to keep track of its state, and the overhead can be noticeable).
I believe the default for projects built through Visual Studio is /MD.
If you use /MT, your executable won't depend on a DLL being present on the target system. If you're wrapping this in an installer, it probably won't be an issue and you can go either way.
I use /MT myself, so that I can ignore the whole DLL mess.
P.S. As Mr. Fooz points out, it's vital to be consistent. If you're linking with other libraries, you need to use the same option they do. If you're using a third party DLL, it's almost certain that you'll need to use the DLL version of the runtime library.
I prefer to link statically with /MT.
Even though you do get a smaller executable with /MD, you still have to ship a bunch of DLLs to make sure the user gets the right version for running your program. And in the end your installer is going to be BIGGER than when linking with /MT.
What's even worse, if you choose to put your runtime libraries in the windows directory, sooner or later the user is going to install a new application with different libraries and, with any bad luck, break your application.
The problem you will run into with /MD is that the target version of the CRT may not be on your users machine (especially if you're using the latest version of Visual Studio and the user has an older operating system).
In that case you have to figure out how to get the right version onto their machine.
from http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx:
/MT Defines _MT so that multithread-specific versions of the run-time routines are selected from the standard header (.h) files. This option also causes the compiler to place the library name LIBCMT.lib into the .obj file so that the linker will use LIBCMT.lib to resolve external symbols. Either /MT or /MD (or their debug equivalents /MTd or /MDd) is required to create multithreaded programs.
/MD Defines _MT and _DLL so that both multithread- and DLL-specific versions of the run-time routines are selected from the standard .h files. This option also causes the compiler to place the library name MSVCRT.lib into the .obj file.
Applications compiled with this option are statically linked to MSVCRT.lib. This library provides a layer of code that allows the linker to resolve external references. The actual working code is contained in MSVCR71.DLL, which must be available at run time to applications linked with MSVCRT.lib.
When /MD is used with _STATIC_CPPLIB defined (/D_STATIC_CPPLIB) it will cause the application to link with the static multithread Standard C++ Library (libcpmt.lib) instead of the dynamic version (msvcprt.lib) while still dynamically linking to the main CRT via msvcrt.lib.
So if I am interpreting it correctly then /MT links statically and /MD links dynamically.
If you are building executable that uses other dlls or libs than /MD option is preferred because that way all the components will be sharing same library. Of course this option should match for all the modules involved i.e dll/lib/exe.
If your executable doesn't uses any lib or dll than its anyone's call. The difference is not too much now because the sharing aspect is not into play.
So maybe you can start the application with /MT since there is no compelling reason otherwise but when its time to add a lib or dll, you can change it to /MD with that of the lib/dll which is easy.

Why is runtime library a compiler option rather than a linker option?

I'm trying to build a C/C++ static library using visual studio 2005. Since the selection of the runtime library is a compile option, I am forced to build four variations of my library, one for each variation of the runtime library:
/MT - static runtime library
/MD - DLL runtime library
/MTd - debug static runtime library
/MDd - debug DLL runtime library
These are compiler options, not linker options. Coming from a Linux background, this seems strange. Do the different runtime libraries have different calling conventions or something? Why can't the different runtime libraries be resolved at link time, i.e. when I link the application which uses my static library?
These options may add defines (__DLL and __DEBUG for example) that are used in the runtime library header files. One common thing to do is to add __declspec(dllimport) to function declarations when linked dynamically.
The compiler also seems to use these to assist the linker in linking to the correct libraries. This is explained in the MSDN.
One side effect of the C preprocessor definitions like _DLL and _DEBUG that zdan mentioned:
Some data structures (such as STL containers and iterators) may be sized differently in the debug runtime, possibly due to features such as _HAS_ITERATOR_DEBUGGING and _SECURE_SCL. You must compile your code with structure definitions that are binary-compatible with the library you're linking to.
If you mix and match object files that were compiled against different runtime libraries, you will get linker warnings such as the following:
warning LNK4098: defaultlib 'LIBCMT' conflicts with use of other libs
The compiler needs to know if you are generating single threaded or multi-threaded code. By default the compiler generates thread safe code (multi-threaded). You have to tell it if you want single thread code.If you change the default the compiler changes the default run-time library (you can always override this in the linker command options, just be sure that the library you pick has the same code structure as your object files: single-threaded static, multi-threaded static or multi-threaded DLL). Note that there is no single-threaded DLL option (by definition the run-time library DLL will have been built as thread safe as it is shared by multiple apps).
If you ignore the static runtime then you get the same options as Linux.
I know static runtime can be usful but I have never actually needed it. Also it leads to potential problems dealing with allocation/deallocation of memory and as a result I find it easier to just to use the DLL runtime.
Having Release/Debug version is the same as Linux/Unix though.
Though for effeciency I reasons I alos build a single thread and multi thread versions of libraries.
I believe the reason behind this is that SEH (structured exception handler) code will be generated differently depending on which runtime library you link against.
There is different machine code generated for DLL's and static libraries.
And on Linux you have to do the same, the compiler flag is called -fPIC if you want to build a shared library. Otherwise on AMD64 and SPARC (and maybe others) it will crash. On i386 architecture the linker is clever enough and does not share the library in memory so it won't crash.