Please tell me what difference between pthread versions: VC2, VCE2 and VSE2? How to choose which of them I must use with Visual C++ Express 2010 for Mongoose webserver library?
Thank you!!!
VCE - MSVC dll with C++ exception handling
VSE - MSVC dll with structured exception handling
VC - MSVC dll with C cleanup code
Which one you'd want to use with VC++ Express 2010 depends on how you want pthread clean up to be handled. If you're linking this to the Mongoose webserver (which I'm not familiar with), I think you'll want to use the exception handling model as that code is compiled with.
The pthreads Win32 library goes into a fair bit of detail:
Library naming
Because the library is being built
using various exception handling
schemes and compilers - and because
the library may not work reliably if
these are mixed in an application,
each different version of the library
has it's own name.
Note 1: the incompatibility is really
between EH implementations of the
different compilers. It should be
possible to use the standard C version
from either compiler with C++
applications built with a different
compiler. If you use an EH version of
the library, then you must use the
same compiler for the application.
This is another complication and
dependency that can be avoided by
using only the standard C library
version.
Note 2: if you use a standard C
pthread*.dll with a C++ application,
then any functions that you define
that are intended to be called via
pthread_cleanup_push() must be
__cdecl.
Note 3: the intention was to also name
either the VC or GC version (it should
be arbitrary) as pthread.dll,
including pthread.lib and libpthread.a
as appropriate. This is no longer
likely to happen.
Note 4: the compatibility number was
added so that applications can
differentiate between binary
incompatible versions of the libs and
dlls.
In general: pthread[VG]{SE,CE,C}c.dll
pthread[VG]{SE,CE,C}c.lib
where: [VG] indicates the compiler
V - MS VC, or G - GNU C
{SE,CE,C} indicates the exception
handling scheme SE - Structured EH,
or CE - C++ EH, or C - no exceptions
- uses setjmp/longjmp
c - DLL compatibility number
indicating ABI and API
compatibility with applications built against
any snapshot with the same compatibility number.
See 'Version numbering' below.
The name may also be suffixed by a 'd'
to indicate a debugging version of the
library. E.g. pthreadVC2d.lib.
Debugging versions contain additional
information for debugging (symbols
etc) and are often not optimised in
any way (compiled with optimisation
turned off).
For example:
pthreadVSE.dll (MSVC/SEH)
pthreadGCE.dll (GNUC/C++ EH)
pthreadGC.dll (GNUC/not dependent on
exceptions) pthreadVC1.dll (MSVC/not
dependent on exceptions - not binary
compatible with pthreadVC.dll)
pthreadVC2.dll (MSVC/not dependent on
exceptions - not binary compatible
with pthreadVC1.dll or pthreadVC.dll)
The GNU library archive file names
have correspondingly changed to:
libpthreadGCEc.a libpthreadGCc.a
If you want to see what the differences are for each of these clean up models, search for "__CLEANUP" in the pthreads Win32 source (there are only a few places where the different clean up models come into play).
Related
I have built a ADA static library and I share it by providing '.a' and ALI files.
Everything works fine while I use the same GNAT compiler version than the one used to build the static library.
But with another compiler version, the ALI files are considered as not valid (the compiler version is stored in all ALI files), and the compiler needs source files to rebuild ALI files.
Is there a solution to avoid this problem ?
updated on 12/11/2015 : We did some tests (with ALI library files in ready only), but we still have the following errors :
error: "package1.adb" and "prog.adb" compiled with different GNAT versions
error: "prog.adb" must be recompiled ("system.ads" has been modified)
So, I think we have to use the same compiler version for the library and the program.
If you are using gnatmake, make the ALI files read-only, so that the compiler does not try to recompile them (you are of course responsible for ensure that the object files are compatible, but this is in general the case).
If you are using project files, add a
for Externally_Built use "True";
attribute to achieve the same effect.
Answer from AdaCore :
This isn't supported: the Ada ABI (Application Binary Interface) is not guaranteed to stay the same across versions (and indeed does change regularly), so you cannot mix objects compiled with different versions of GNAT, you really need to ensure consistency in all your libraries.
So, it's not possible.
The definition of mbstate_t has changed from:
typedef int mbstate_t;
to
typedef struct _Mbstatet
{ // state of a multibyte translation
unsigned long _Wchar;
unsigned short _Byte, _State;
} _Mbstatet;
typedef _Mbstatet mbstate_t;
This is not backwards compatible and seems to imply all components of a Windows desktop application will need recompiling with VS 2015 if I am to use VS 2015. Obviously "all" is too strong here, only components using mbstate_t are affected. However, that's still not a good situation.
Are we expected to recompile if we migrate to VS 2015? Am I missing something here which means this isn't an issue?
Given that this struct has changed I have bigger concerns that there may be other breaking changes between VS 2013 and 2015. Is there a list of these anywhere?
Note:
I've already asked this question on MSDN but my gut tells me more eyes will be on it on Stack Overflow: https://social.msdn.microsoft.com/Forums/vstudio/en-US/8e50f348-0b6d-442c-8a1e-b1b8a4288fbc/mbstatet-is-not-backwards-compatible-between-vs-2015-and-vs-2013?forum=vcgeneral#8e50f348-0b6d-442c-8a1e-b1b8a4288fbc
To answer the question. Yes, you are expected to recompile everything if you wish to update to newer versions of Visual Studio. MS reserve the right to change any part of toolchain and libraries. There are clear examples of C headers and C++ headers changing. Plenty of other things could change as well which would make binary compatibility between versions difficult or impossible.
Some discussion / opinion
In my mind it is not 100% obvious that you'd need to recompile everything when updating to a newer version of the toolchain. Forcing a user to recompile everything to update to a new toolchain can be quite burdensome. In large projects you may be dependent on a lot of 3rd party code which you have no way of recompiling. Many SDK expend a lot of energy in ensuring backwards compatibilty so that users don't have to do this.
Interestingly the linker makes no effort to disallow linking against libraries built with older versions of the toolchain. It doesn't even warn! This behaviour might imply that it's acceptable to link old libraries with new code.
Anyway, I could waffle about this all day. One thing I wanted to point out is that if you know what you're doing then it is possible to link binaries built with older versions of VS against newer versions. You have to be very clear about what declarations (effectively your header files) your code was built against and know that these declarations either haven't changed or they have changed in a way that doesn't cause runtime errors. You also have to be sure that the compiler hasn't changed the way it handles builtins/intrinsics etc. in a sufficient way to hurt you. For example, the use of a try/catch block with MSVC will cause code to be automatically generated to handle exceptions. This will lead to implicit calls to functions provided by the runtime libs. That could easily change version to version and you could be left with undefined symbols or unexpected behaviour.
Proceed with caution :)
It used to be that Visual C++ actually did try to maintain C runtime library backwards compatibility at the object file (and thus static library) level. Opaque types like mbstate_t might change their internal representation, but they wouldn't change their size. This allowed an object file compiled with older versions of the CRT headers to work when linked with a newer version of the CRT.
(Note that this doesn't apply when CRT objects are passed across DLL boundaries. Multiple CRTs in the same program, whether statically or dynamically linked, are not compatible.)
This mostly only applied to C code however. The Standard C++ Library was not backwards compatible at all, and there are actually linker checks to enforce this. (Though not if the out of date object files were compiled with Visual Studio 2008 or earlier.) Also the C++ ABI is subject to change between major releases, so potentially the layout of C++ objects can change.
However as you've noticed with Visual Studio 2015, the C runtime library is no longer backwards compatible. The CRT went through a major refactoring and many things changed. Most of it is no even longer part of Visual Studio, and instead is now a part of the Windows operating system. As you've also noticed, there's no error or warning when you to try to link older binaries with the new CRT. As the old CRT didn't include any version symbols in the compiled object files, so there's way it can know if they were compiled using the old CRT headers.
We have Oracle 11 running on HP-UX 11.31 and gcc 4.4.3. It seems that there is no way to link to occi, because it was built with aCC. Is there any workaround for this?
I had the silly idea that I could somehow build a library that basically proxied the connection - build the library with aCC in some way that could be linked to by gcc. Is this possible?
No, there isn't a way around that.
Different C compilers have interchangeable code using a standard ABI. You can mix and match their object code more or less with impunity.
However, different C++ compilers have a variety of different conventions that mean that their object code is not compatible. These relate to class layout (especially in multiple inheritance hierarchies and the dreaded 'diamond-of-death'), but also in name mangling conventions and exception handling. The name mangling schemes are deliberately made different so that you cannot accidentally link objects from one compiler with another.
Generally, if libraries are built using a C++ compiler, you have to link your code using the same - or at least a compatible - C++ compiler. And that almost invariably means a compiler from the same family. For example, you might be able to use G++ 4.5.0 even if the code was built with G++ 4.4.2. However, you won't be able to mix aCC with G++.
I have encountered an unexpected Access Error while running a project I've built using two different versions of Visual Studio. My general configuration is as follows:
LibA is a static lib, static runtime linkage, msvc 8.0
LibB is a static lib, static runtime linkage, msvc 9.0
My target project for integration is a msvc 9.0 COM dll, which statically links the above libraries
This project builds, but crashes up at runtime with an access violation in some STL code. The stack seems to indicate that I've passed through headers both versions (8 and 9) during a call into a stream insertion operator. I realize that this is a problem.
Somehow, this call:
ost << std::dec << port_; //(originating from an object in LibA)
...descends through the following stack trace:
std::basic_ostream::operator<<(...) (ostream:283, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::put(...) (xlocnum:888, msvc 8.0 version <-- expected, since LibA was built with this version)
std::num_put::do_put(...) (xlocnum:1158, msvc 9.0 version!! !##$!%! <-- not expected, since LibA was built with msvc 8.0)
std::ios_base::flags() (xiosbase:374, msvc 9.0 version <-- follows from above)
The access violation happens in std::ios_base::flags(). I suspect it is due to the mix of implementations in the call stack (although I am not sure).
My questions are.
1.) Is the likely cause of this access violation the mixing of msvc header implementations?
2.) Is there a way to prevent these implementations from mixing?
3.) Is there a better way to configure these three projects for integration (assuming moving LibA from msvc 8.0 is undesirable)?
I am aware of the ideas raised in this question and this one. Here I am most interested in this specific problem, and if there is some way to avoid it.
Any insights would be appreciated.
You can't use different STL implementation in the same project. This means even different versions from the same compiler. If your LibA has a function that accepts std::vector as an argument you are only allowed to pass vector object from STL that LibA was built with. This is why many C++ libraries expose only C API.
Either you change your API or you rebuild all your projects using the same compiler.
You are doing something that you shouldn't. You are in the world of undefined behavior. There is no point in trying to debug this particular crash. Even if you managed to make this line work you would get a new crash somewhere else.
There is no guarantee of library binary compatibility between major versions of MSVC. STL code is mostly template code that gets expanded into your code. So you're static libraries probably have incompatible chunks of STL code inside of them.
In general, this shouldn't be a problem, unless that STL code is part of the interface to the library. For example, if you pass iterators or a reference to a vector from one library to another, you're in trouble.
The best solution is to build everything with the same version of the compiler. If you can't do that (e.g., if the one of the libraries is from a third-party), you're probably stuck.
Which headers should I not use if I don't want my program to be linked with any of msvc*.dll ?
At the moment my application uses:
kernel32
user32
shell32
msvcp90
msvcr90
I want to get rid of the bottom two files. I don't mind if I will have to rewrite certain aspects of the program.
Because I know if you code in C and then link it won't link any msvc's
I believe you have to change the way the CRT is linked into your program. I think for that you have to change the C++->Code Generation->Runtime-Library to the static version. This is for Visual Studio 2005, don't know about newer versions.
Those libraries contain the C++ runtime - heap management and other stuff hard to get rid from.
You could link the C++ statically instead - use "C++ -> Code Generation -> Runtime Library" setting. Then you will not need those .dll files. However this is not the recommended way - if a vulnerability is found in the C++ runtime you'll have to recompile and reship your program.
Static link is the right answer. A related bit of advice is to use depends.exe to see what functions your exe is actually hitting in the dependent dlls. Those dependencies might be due to explicit use on your part or due to CRT implementation that you don't explicitly invoke.