3 ms·
Compiling to C would be better. Using C++ libraries from anything outside C++ compiled by the same exact compiler and same exact version of it as the library wa
by bluecalm 11y ago
Compiling to C would be better. Using C++ libraries from anything outside C++ compiled by the same exact compiler and same exact version of it as the library was is a royal pain.
On the other hand using C libraries is super easy from any language and something compiled 10 years ago still works today.
- tjradcliffe 11y agoWe could call it cfront: https://en.wikipedia.org/wiki/Cfront https://en.wikipedia.org/wiki/Cfront
- nly 11y agoYou only get ABIstab in C if you never change the size or layout of your structs, or completely hide everything behind pointers and allocate everything on the heap (maybe a little on the stack if your library is amenable to using callbacks - blargk!). The rules[0] for C++ aren't really any different, you just notice it more. When you start shooting for ABIstab, without putting in a lot of extra work, you start losing the nice semantics and APIs you're used to. In the C world, because of the limited capabilities of the language, library developers have never been able to do better, so application developers are used to suffering crappy APIs and working extra hard to get stuff done. C++98 code out of GCC has been ABI stable for over 10 years now btw, and we also have some pretty great tools for detecting ABI breakage now, like abi-compliance-checker[1] [0] https://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++#The_Do.27s_and_Don.27ts https://techbase.kde.org/Policies/Binary_Compatibility_Issue... [1] http://ispras.linuxbase.org/index.php/ABI_compliance_checker http://ispras.linuxbase.org/index.php/ABI_compliance_checker
- bluecalm 11y ago>>C++98 code out of GCC has also been ABI stable for over 10 years now btw I was specifically picking on Visual Studio and vendors who decided to distribute C++ dlls. Sometimes they provide several versions depending on which Visual Studio version you have installed at the moment.
- deleted 11y ago[deleted]
- datenwolf 11y ago> You only get ABIstab in C if you never change the size or layout of your structs Well, and you can append new elements to a struct and are guaranteed that the initial sequence of common elements is identical. This is not mentioned explicitly in the C language standard, but it follows as a corollary from point 6.5.2.2.5 of the language standard: > One special guarantee is made in order to simplify the use of unions: if a union containsseveral structures that share a common initial sequence (see below), and if the unionobject currently contains one of these structures, it is permitted to inspect the commoninitial part of any of them anywhere that a declaration of the complete type of the union isvisible. Two structures share acommon initial sequenceif corresponding members havecompatible types (and, for bit-fields, the same widths) for a sequence of one or moreinitial members. Consider a.h struct a { char aye; short bee; int cee; long dee; }; a.c #include "a.h" int aye(struct a a) { return a.aye; } b.h struct b { char aye; short bee; int cee; long dee; double eee; }; b.c #include "b.h" int bee(struct b b) { return b.bee; } Now if we add c.h #include "a.h" #include "b.h" union ab { struct a a; struct b b; }; The language standard warrants, that the common initial sequence of both structures can be used interchangeably in that union. Since however compilation units a.c and b.c are processed individually without knowledge of union ab this enforces the compiler to use the same memory layout for an initial sequence of member elements for either struct. Hence it is legal to extend structs without out altering the memory layout of the previous elements.
- nly 11y agoYou get the same guarantee in C++, as well as a language mechanism to exploit it (inheritance). You still can't pass structs by value across library boundaries in either language without fixing your ABI though. This isn't a language intrinsic problem: it boils down to the linker model, which only C and C++ share.
- datenwolf 11y ago> This isn't a language intrinsic problem: it boils down to the linker model, which only C and C++ share The linker coudln't care less about this part of the ABI (calling conventions). For example passing a function pointer to a different library (callback) the linker is completely oblivious to. Heck, the functions which pointers are being being passed around could have been compiled at runtime (JIT). Calling convention ABIs are a compiler thing, as it's the compiler that emits the machine code that's responsible for setting up the frame in which a function executes. And calling conventions is, where C and C++ differ. On the language level there are not calling conventions (how could there be, as those strongly depend on the machine architecture). However for the various operating systems out there you can find detailed calling conventions for C, but seldomly for C++. And these platform specific C calling conventions usually tightly control both how function (stack) frames are created, which registers may be clobbered, but they also control the memory layout that a C compiler for that platform shall apply on structs. For example the SysV AMD64 ABI strictly nails down the specifics of aggregate type memory layout and function parameter passing. All compilers following that spec will produce code that's compatible with each other, even across library boundaries.