Why ISO/ANSI didn\'t standardize C++ at the binary level? There are many portabi
ID: 642360 • Letter: W
Question
Why ISO/ANSI didn't standardize C++ at the binary level? There are many portability issues with C++, which is only because of lack of it's standardization at the binary level.
Don Box writes, (quoting from his book Essential COM, chapter COM As A Better C++)
C++ and Portability
Once the decision is made to distribute a C++ class as a DLL, one is faced with one of the fundamental weaknesses of C++, that is, lack of standardization at the binary level. Although the ISO/ANSI C++ Draft Working Paper attempts to codify which programs will compile and what the semantic effects of running them will be, it makes no attempt to standardize the binary runtime model of C++. The first time this problem will become evident is when a client tries to link against the FastString DLL's import library from a C++ developement environment other than the one used to build the FastString DLL.
Are there more benefits Or loss of this lack of binary standardization?
Explanation / Answer
Languages with binary-compatible compiled form are a relatively new phase[*], for example the JVM and .NET runtimes. C and C++ compilers usually emit native code.
The advantage is that there is no need for a JIT, or a bytecode interpreter, or a VM, or any other such thing. For example, you can't write the bootstrap code that runs at machine startup as nice, portable Java bytecode, unless perhaps the machine can natively execute Java bytecode, or you have some kind of converter from Java to a non-binary-compatible native executable code (in theory: not sure this can be recommended in practice for bootstrap code). You could write it in C++, more or less, albeit not portable C++ even at the source level, since it will do a lot of messing with magic hardware addresses.
The disadvantage is that of course native code only runs at all on the architecture it was compiled for, and the executables can only be loaded by a loader that understands their executable format, and only link with and call into other executables for the same architecture and ABI.
Even if you get that far, linking two executables together will only actually work correctly as long as: (a) you don't violate the One Definition Rule, which is easy to do if they were compiled with different compilers/options/whatever, such that they were using different definitions of the same class (either in a header, or because they each statically linked against different implementations); and (b) all relevant implementation details such as structure layout are identical according to the compiler options in force when each was compiled.
For the C++ standard to define all of this would remove a lot of the freedoms currently available to implementers. Implementers are using those freedoms, especially when writing very low-level code in C++ (and C, which has the same issue).
If you want to write something that looks a bit like C++, for a binary-portable target, there's C++/CLI, which targets .NET, and Mono so that you can (hopefully) run .NET elsewhere than Windows. I think it's possible to persuade MS's compiler to produce pure CIL assemblies that will run on Mono.
There are also potentially things that can be done with for example LLVM to create a binary-portable C or C++ environment. I don't know that any widespread example has emerged, though.
But these all rely on fixing a lot of things that the C++ makes implementation-dependent (such as the sizes of types). Then the environment that understands the portable binaries, must be available on the system where the code is to run. By allowing non-portable binaries, C and C++ can go places where portable binaries can't, and that's why the standard doesn't say anything at all about binaries.
Then on any given platform, implementations usually still don't provide binary compatibility between different sets of options, although the standard isn't stopping them. If Don Box doesn't like that Microsoft's compilers can produce incompatible binaries from the same source, according to compiler options, then it's the compiler team he needs to complain about. The C++ language does not forbid a compiler or an OS from pinning down all the necessary details, so once you limit yourself to Windows it's not a fundamental problem with C++. Microsoft has chosen not to do so.
The differences often manifest as one more thing that you can get wrong and crash your program, but there may be considerable gains to be made in efficiency between, for example, incompatible debug vs release versions of a dll.
[*] I'm not sure when the idea was first invented, probably 1642 or something, but their current popularity is relatively new, compared to the time when C++ committed to the design decisions which prevent it defining binary-portability.
Related Questions
Navigate
Integrity-first tutoring: explanations and feedback only — we do not complete graded work. Learn more.