Link compatibility among C compilers?

D

Derek

As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun).

What I'm curious about is why this compatibility exists in the
absence of a standard C ABI?

What encourages C compiler vendors to agree on implementation
issues such as alignment, packing, etc., such that their object
files are compatible?

I've heard it said that compiler vendors who don't want to re-
implement the whole standard C library have to use the platform
ABI to conform to the platform standard library, but I was always
under the impression that most compiler vendors provided their
own standard library.

I'd appreciate could share their insights as to why this
apparently high degree of object compatibility exists among C
compilers.

Also, are there any well defined areas where C compilers are
likely to be incompatible?

Thank you.
 
B

Ben Pfaff

Derek said:
As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun).

What I'm curious about is why this compatibility exists in the
absence of a standard C ABI?

Most platforms have a well-defined ABI. For example, Linux on
i386 tends to conform to the System V Release 4 ABI for i386,
which you can find pretty easily with a web search.
 
E

Eric Sosman

Derek said:
As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun).

What I'm curious about is why this compatibility exists in the
absence of a standard C ABI?

What encourages C compiler vendors to agree on implementation
issues such as alignment, packing, etc., such that their object
files are compatible?

For starters, the underlying platform provides an ABI, and
both the C library and the code generated by the C compiler
pretty much have to respect it. As a user, you want your C
code to be able to invoke the platform's services and make
sense out of the results, so all implementations begin with
a certain amount of commonality.

Then there's the issue of non-Standard libraries. Imagine
setting out to produce a new, super-duper C implementation for
a platform that already has an old, rowsty-frowsty one (I'm
quoting from your marketing literature). Do you think it would
be economically viable to require your potential customers to
recompile *everything* in order to link it with code generated
by your implementation? Realize that "everything" may well
include third-party libraries to which your customers do not
have source.
 
R

Richard Tobin

As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun). [...]
but I was always
under the impression that most compiler vendors provided their
own standard library.

When you use gcc on a Sun, aren't you using Sun's libraries (except
maybe for a few functions in libgcc)?

And it would be a real pain if you had to have multiple versions of
(non-standard) libraries that you installed, one for each compiler you
used.

If I were considering installing a new compiler, having to replace
all the libraries on the system would almost certainly ansure that
I didn't do it.

-- Richard
 
A

Alan Balmer

As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun).

Don't count on it. Compilers are free to produce different linkage
mangling and different calling sequences. What's more, runtime
libraries often use incompatible helper routines.
What I'm curious about is why this compatibility exists in the
absence of a standard C ABI?

What encourages C compiler vendors to agree on implementation
issues such as alignment, packing, etc., such that their object
files are compatible?

I've heard it said that compiler vendors who don't want to re-
implement the whole standard C library have to use the platform
ABI to conform to the platform standard library, but I was always
under the impression that most compiler vendors provided their
own standard library.

I'd appreciate could share their insights as to why this
apparently high degree of object compatibility exists among C
compilers.

I'm curious as to where you got the impression that a high degree of
compatibility exist.
 
D

Derek

Alan said:
> I'm curious as to where you got the impression that a
> high degree of compatibility exist.

Just that in all my years of coding I have never given
much thought to which compiler third-party C libraries
were compiled with. They just worked regardless of my
compiler choice.
 
A

Alan Balmer

Just that in all my years of coding I have never given
much thought to which compiler third-party C libraries
were compiled with. They just worked regardless of my
compiler choice.

Either you have been very fortunate, or worked with a limited set of
compilers, or (perhaps more likely) worked mostly with shared
libraries (DLLs). The interface to shared libraries is more standard.
Static libraries intended to be sold for a variety of compilers come
in various flavors, or if distributed as source, with lots of
conditional compilation. Even such things as the exported names vary:
what the compiler sees as "foo" may be emitted as a linkage to "_foo"
or "foo_", for example.

The Watcom compilers provide facilities to control both mangling of
the linkage names and the calling conventions.
 
C

Chris Barts

I used Google

http://www.google.com/

to search for

+"Application Binary Interface"

and I found lots of stuff.

At the risk of feeding the Tisdale, I'd point out that ABIs mainly
standardize the interface to the OS itself, and may not be followed by the
object files meant to be linked into larger programs.

However, few compilers in the Unix world (and many, many OSes follow this
example) actually do linking. The system has a special-purpose linking
program, and the binary format that program expects forms a de facto
standard for all compiled programs to follow.

(Hell, this thread began strictly OT, and I don't mind. I do care that
misleading info not be spread willy-nilly.)
 
D

Dan Pop

In said:
At the risk of feeding the Tisdale, I'd point out that ABIs mainly
standardize the interface to the OS itself, and may not be followed by the
object files meant to be linked into larger programs.

This is simply not true. That's why they are called "*Application*
Binary Interface" and not "Operating System Binary Interface". An ABI
describes everything related to one function calling another: how
parameters are passed to the callee and how the return value is passed
back to the caller. Having this defined by the ABI and not by one
compiler or another ensures interoperability between modules compiled with
different compilers.

It is true that the ABI itself doesn't, typically, define the format of
the object file itself, but each platform (with insignificant exceptions)
defines it (or picks one commonly supported one) and all the language
translators comply with that specification.

Dan
 
D

Dan Pop

In said:
As I understand it there is a good amount of link compatibility
among C compilers. For example, I can compile main.c with GCC
and func.c with Sun One and link the objects using either linker
(GNU or Sun).

It's more than that: there's a good amount of link compatibility among
*all* compilers used on any given modern platform.
What I'm curious about is why this compatibility exists in the
absence of a standard C ABI?

Each platform defines its own ABI, in a language independent way.
It also defines a common format for the object files. This is all that's
needed to have modules compiled with different compilers (not necessarily
for the same language) linked together in a working executable.
What encourages C compiler vendors to agree on implementation
issues such as alignment, packing, etc., such that their object
files are compatible?

The ABI specification of the target platform. gcc behaves differently
on different platforms, in order to comply with the local ABI.
I've heard it said that compiler vendors who don't want to re-
implement the whole standard C library have to use the platform
ABI to conform to the platform standard library, but I was always
under the impression that most compiler vendors provided their
own standard library.

There is no general rule. gcc always uses the local implementation of
the standard library, many other compilers come with their own libraries
but also use part of the local libraries: it is a royal pain in the ass
to implement the interface with the OS, so you simply use the low level
stuff already existing as part of the local implementation of the standard
libraries.
I'd appreciate could share their insights as to why this
apparently high degree of object compatibility exists among C
compilers.

Imagine that you were a compiler writer. Would you design your
compiler in a manner requiring you to reimplement a lot of OS dependent
stuff from scratch?

On bare bones platforms, like, e.g. CP/M-80, that didn't provide any
common software infrastructure (except for a few OS primitives), it was
not uncommon for language implementors to define *everything* from
scratch, except the format of the executable files, of course. And by
everything I mean exactly that: the size and representation of the data
types, the calling conventions, the object file format, the linker, the
libraries. At best, you could combine modules produced by different
compilers of the same vendor. On platforms even more primitive than
CP/M-80 (many home computers of the early eighties) you did not even
have object files: you had to recompile all your sources in a single
executable file every time you made a change somewhere; the linker was
built into the compiler or the assembler and the run time support module
bundled with the generated code contained the whole language library.
Also, are there any well defined areas where C compilers are
likely to be incompatible?

Not if they are targeting the same platform. They all would try to
implement the standard C features in the same way and, to a certain
extent, to be compatible even at the level of language extensions.

There is one exception, though: some platforms having moved from one
bitness to another, e.g. from 32-bit to 64-bit. It is not uncommon to
have 32 and 64-bit compilers coexisting on such platforms, if they
continue to support applications built for the older format. Or even
have the same compiler work in both modes. In such cases, the linkers
are usually checking that all modules being linked together have been
compiled in the same mode and link them against the right set of
libraries. These are tricky environments: you may use, without realising,
a 32-bit shell combined with native 64-bit commands and not understand
why some things work differently in different contexts: e.g. your 64-bit
application can easily generate files above 4 GB, but, if you redirect
its standard output to a file, that file is limited to 4 GB.

Dan
 
T

Tim Prince

Dan Pop said:
It's more than that: there's a good amount of link compatibility among
*all* compilers used on any given modern platform.
Unfortunately, no, for example, if you stray into linux C++, as many
programmers do, commercial compilers of my acquaintence make modifications
in the installation to adapt differently to match up to gcc-3.2, 3.3, or
3.4. There is even less compatibility with proprietary versions of gcc
still supplied with certain operating systems. Nor can you count on much
compatibility between gcc and commercial Windows compilers.
The situation gets worse when you get into other languages which come with
gcc. Even though they are link compatible with gcc, this does not extend to
link compatibility with commercial compilers for those same languages.
There is one exception, though: some platforms having moved from one
bitness to another, e.g. from 32-bit to 64-bit. It is not uncommon to
have 32 and 64-bit compilers coexisting on such platforms, if they
continue to support applications built for the older format. Or even
have the same compiler work in both modes. In such cases, the linkers
are usually checking that all modules being linked together have been
compiled in the same mode and link them against the right set of
libraries. These are tricky environments: you may use, without realising,
a 32-bit shell combined with native 64-bit commands and not understand
why some things work differently in different contexts: e.g. your 64-bit
application can easily generate files above 4 GB, but, if you redirect
its standard output to a file, that file is limited to 4 GB.
On certain well-known 32/64 bit systems, there is a mode bit set for 64
bits, and if you manage to link 32- and 64-bit binaries into the same
application, or install a 32-bit driver, it simply hangs. I second the
comment about trickiness of keeping 32- and 64-bit library paths straight.
 
C

CBFalconer

Dan said:
.... snip ...

On bare bones platforms, like, e.g. CP/M-80, that didn't provide
any common software infrastructure (except for a few OS primitives),
it was not uncommon for language implementors to define *everything*
from scratch, except the format of the executable files, of course.
...

Back in those days I needed to have a relocatable linkable object
format. Intel had created something to go with their development
platforms (which eventually developed into the ugly format used in
PCs), and I asked them for the definitions. They refused, and
claimed it was proprietary information. So I went my own way, as
I suspect did many others.

SLR systems was just one of those 'others', and Steve Russel
published his. It was orders of magnitude better than the
Microsoft L80 format, which was another (poor one) developed in
the vacuum.

You can read about my format, if you are interested, in the
documentation on my web page for the PascalP system.
 
D

Dan Pop

Unfortunately, no, for example, if you stray into linux C++, as many
programmers do, commercial compilers of my acquaintence make modifications
in the installation to adapt differently to match up to gcc-3.2, 3.3, or
3.4.

Although C++ has the additional problem of no existing standards for
name mangling, I have no problems mixing g++ and icc on Linux:

fangorn:~/tmp 151> cat gcc.cc
void icc(char *);

int main()
{
icc("Hello world");
return 0;
}
fangorn:~/tmp 152> g++ -c -o gcc.o gcc.cc
fangorn:~/tmp 153> cat icc.cc
#include <cstdio>

void icc(char *p)
{
std::puts(p);
}
fangorn:~/tmp 154> icc -o icc.o -c icc.cc
fangorn:~/tmp 155> icc icc.o gcc.o
fangorn:~/tmp 156> ./a.out
Hello world
fangorn:~/tmp 157> g++ icc.o gcc.o
fangorn:~/tmp 158> ./a.out
Hello world

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,770
Messages
2,569,584
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top