APIs and ABIs

Jeroen Dekkers jeroen at dekkers.cx
Sun May 16 09:59:01 UTC 2004

At Sat, 15 May 2004 23:47:06 +0100,
Niall Douglas wrote:
> On 15 May 2004 at 13:18, Neal H. Walfield wrote:
> > > Both the GNU and BSD C libraries offer the same API's eg; size_t
> > > fread(void *buffer, size_t size, size_t count, FILE *stream). Both
> > > use the same compiler (GCC) and so therefore that API will convert
> > > into the same ABI eg; _fread using the same parameter to stack
> > > conversion mechanism (the procedural call convention).
> > 
> > That is complete and utter crap.
> > 
> > The ABI has nothing to do with the compiler: calling conventions, etc.
> > are established by the operating system. 
> No, the ABI is determined by what compiler the operating system was 
> compiled with. C (and C++) implementations are free to choose any 
> procedural calling convention they like. Contrast how Mingw and MSVC 
> mangle their C++ symbols differently. Contrast even within MSVC how 
> you can choose between three different calling conventions. On 
> Windows at least two calling conventions are used throughout the OS 
> depending on what the library designer felt like.
> Go read either the ANSI C or ISO C++ spec if you want confirmation of 
> this.

That's only one very small part of the ABI of a binary. The library
interface is a lot more important and decides the biggest part of the
> > Nothing guarantees that
> > posix defined structures have the same layout or even size (and this
> > is very much part of the ABI).  Not all posix functions are actually
> > functions, many of them may be macros.  The list goes on and this does
> > not even consider versioning schemes, library dependencies or system
> > trap calling conventions.
> In the fread() example above, FILE is an opaque pointer. It could 
> contain anything. For major structures eg; struct stat one finds an 
> amazing invariance of fields and their order. If the structure 
> packing were different one might have a problem, but again everyone 
> using GCC solves that.

In the fread() example, how do you get the error? By looking at
errno. But errno is a macro, which actually calls a function to get
the errno variable. And this function isn't available on FreeBSD.

The stat structure differs in size for every platform, I just tested
this and the structure is 88 bytes on GNU/Linux and 96 on
NetBSD. And there are dozen of other ABI incompatibilities.

Jeroen Dekkers

More information about the Discussion mailing list