(Silly?) question about linkage of C applications

B

Bit byte

I have an application written in C (actually PostgreSQL). The
application appears to have been built using the Mingw set of tools
(mingw compiler tools).

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

If the answer is no, I will be very grateful to know what the technical
reasons are.
 
I

Ian Collins

Bit said:
I have an application written in C (actually PostgreSQL). The
application appears to have been built using the Mingw set of tools
(mingw compiler tools).

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

If the answer is no, I will be very grateful to know what the technical
reasons are.
In general, on the same platform yes they can. Otherwise, how would you
link the platform's libraries?
 
G

Gordon Burditt

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

It doesn't make sense to use (cross) compilers targeted to different
CPUs for different parts of the program to be linked together except
in EXTREMELY RARE circumstances.

There is no guarantee that any linker recognizes the object file
format of any two compilers you choose. (On CP/M, there were a
number of different and highly incompatible object formats from
different vendors) However, there is a fairly good chance that for
any CPU and OS target, compilers for that target will have one
standard object format, especially if they all use the system linker,
assuming there is one supplied with the OS.

There is no guarantee that object created in different modes of
the *SAME* compiler can be meaningfully linked together.
You probably have to use the same options on all linked pieces
(including the system libraries) for:
- 32 vs. 64 bit mode
- packed/non-packed structures
- memory model (small/medium/compact/large/huge/gigantic)
- symbol name-mangling mode (e.g. compiling C vs. C++)
- linkage conventions (among other issues, there are
"pascal" vs. "C" calling conventions in MS-DOS)
- position-independent code vs. not.

The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

There's no guarantee that a given compiler can be used to create a
shared library, period, even if the OS supports them. For example,
on some systems, shared libraries require position-independent code,
and a compiler might not support that.
If the answer is no, I will be very grateful to know what the technical
reasons are.

There are lots of low-level details about how shared libraries
work, including linkage conventions, that need not work the same
in all compilers.

Gordon L. Burditt
 
G

Guest

Ian said:
In general, on the same platform yes they can. Otherwise, how would you
link the platform's libraries?

Even on the same platform, not necessarily. The stack alignment forced
and assumed at function calls may be different, as a real-world example.
 
I

Ian Collins

Harald said:
Even on the same platform, not necessarily. The stack alignment forced
and assumed at function calls may be different, as a real-world example.
OK, I'll specialise a bit more - on most UNIX platforms (where there the
OS linker is used) they can.
 
G

Guest

Ian said:
OK, I'll specialise a bit more - on most UNIX platforms (where there the
OS linker is used) they can.

Stack alignment is a compiler issue, not a linker issue. The problem is
with code as simple as

void f(void) {
int a[4] = { 0 };
}

If a compiler can assume a four word stack alignment, it may be able to
use a special instruction to zero all of a[0 ... 3] at once. If another
compiler calls f(), but simply word-aligns the stack, the special
instruction may cause a runtime abort. I'm not sure how the linker
could change this.
 
B

Ben C

I have an application written in C (actually PostgreSQL). The
application appears to have been built using the Mingw set of tools
(mingw compiler tools).

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

If the answer is no, I will be very grateful to know what the technical
reasons are.

There's no guarantee, the two things that are most likely to go wrong:

1. Calling convention (how parameters are passed to functions). But in
practice these days many toolchains use cdecl (a particular calling
convention) so you usually get away with it. Many compilers provide
some non-standard decorations you can put around function definitions
and declarations to ensure a particular convention is used. ("extern
__cdecl" that kind of thing). So you may need to add decorators to
the declarations in the headers of the library you're extending, or
to the definitions of functions in your code that the library calls
back.
2. Structure packing. Suppose you write:

struct thing
{
int x;
char y;
int z;
};

in a header file, and include this in sources you build with two
different compilers. Each compiler may have a different idea how to
lay out the struct in memory (different amounts of padding between
and after the members). This can cause nasty problems if code in the
two modules ever shares an instance of one of the structures.

This is best avoided by not putting struct definitions in headers,
but you can't help it if the code you're extending did. Compilers
often have extensions like #pragma pack so you can tweak your
compiler so it packs structs the same as the mingw compiler used to
build the other stuff.

So, it is usually possible if you have to, but you might need to use
some non-standard compiler extensions.

This has always been a problem for people who wanted to ship an SDK in
binary form without mandating a particular compiler. Nowadays it's
becoming more common for people to ship the source with the SDK so the
customer just builds everything with their choice of compiler. It means
the SDK people have to write portable C, which is no bad thing, and in
other ways is generally better for everyone.
 
I

Ian Collins

Harald said:
Ian said:
OK, I'll specialise a bit more - on most UNIX platforms (where there the
OS linker is used) they can.


Stack alignment is a compiler issue, not a linker issue. The problem is
with code as simple as

void f(void) {
int a[4] = { 0 };
}

If a compiler can assume a four word stack alignment, it may be able to
use a special instruction to zero all of a[0 ... 3] at once. If another
compiler calls f(), but simply word-aligns the stack, the special
instruction may cause a runtime abort. I'm not sure how the linker
could change this.
Well I've never seen any problems on any of the UNIX/Linux systems I
have used, after all, not matter what compiler you use, you still have
to link (and work!) with the system's libraries.
 
G

Guest

Ian said:
Harald said:
Ian said:
Harald van Dijk wrote:

Ian Collins wrote:


Bit byte wrote:


I have an application written in C (actually PostgreSQL). The
application appears to have been built using the Mingw set of tools
(mingw compiler tools).

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

If the answer is no, I will be very grateful to know what the technical
reasons are.


In general, on the same platform yes they can. Otherwise, how would you
link the platform's libraries?


Even on the same platform, not necessarily. The stack alignment forced
and assumed at function calls may be different, as a real-world example.


OK, I'll specialise a bit more - on most UNIX platforms (where there the
OS linker is used) they can.


Stack alignment is a compiler issue, not a linker issue. The problem is
with code as simple as

void f(void) {
int a[4] = { 0 };
}

If a compiler can assume a four word stack alignment, it may be able to
use a special instruction to zero all of a[0 ... 3] at once. If another
compiler calls f(), but simply word-aligns the stack, the special
instruction may cause a runtime abort. I'm not sure how the linker
could change this.
Well I've never seen any problems on any of the UNIX/Linux systems I
have used, after all, not matter what compiler you use, you still have
to link (and work!) with the system's libraries.

All four word-aligned stacks are also word-aligned, so if that's what
the system library assumes, no problem. The standard library would need
to use platform-specific hacks to only add multiples of 4*sizeof(int)
to the stack pointer if callback functions are used, but that's
certainly possible to do, even automatically, depending on the
compiler. I can't find a concrete example of this right now, though.

Another possibility for incompatibilities are in how large structs are
returned from functions, when the standard library only returns small
structs, or what size enum types and _Bool have, when the standard
library doesn't rely on those. Both of those are extremely easy to find
examples of, even, since GCC lets you change these (except for _Bool)
using compiler options.
 
J

jacob navia

Harald van Dijk a écrit :
Even on the same platform, not necessarily. The stack alignment forced
and assumed at function calls may be different, as a real-world example.

No, under Unix there is the ABI (Application Binary Interface) and under
windows there is the implicit ABI of Microsoft. Stack alignment anyway
is dictated by the processor and not the ABI.
 
M

Mark McIntyre

Harald van D?k a écrit :

No, under Unix there is the ABI (Application Binary Interface) and under
windows there is the implicit ABI of Microsoft. Stack alignment anyway
is dictated by the processor and not the ABI.

Apparently you've not come across the various options in the MS
compiler suite to change alignment. If you fool with this, you can
trivially generate link errors even with other MS libraries compiled
using hte same tools. And in days of yore, I recall frequently having
to tweak compiler options to ensure that MSC libraries would link with
Watcom C.

I've not tried this on Unix or Linux, but if the same flexibility
didn't exist, I'd be fairly surprised.

--
Mark McIntyre

"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan
 
D

David Wade

Bit byte said:
I have an application written in C (actually PostgreSQL). The
application appears to have been built using the Mingw set of tools
(mingw compiler tools).

I want to write an extension library library to be used by this
application. Do I have to use the same compiler used to create the
application - or is this irrelevant - i.e. can I use ANY compiler to
write the extension library.

It depends what the extension library does and how its linked etc.
The larger question I want to ask really (for the purists amongst you
who will think this is a platform specific question) is:

Can a C application built with one compiler load and use a shared
library built by another compiler?

I would say in general "NO".
If the answer is no, I will be very grateful to know what the technical
reasons are.
Here are a few:-

1) The header files may be different. For example "<stdio.h>" then that
defines a "FILE" structure. They definition of "FILE" may well be different
between compilers. You may be able to get round this by using the header
files from the other compiler....

2) On some platforms, especially those that don't have a stack pointer
defined, e.g. IBM 370 Mainframe for one, the calling conventions are not
fixed. One compiler might generate code that use R11 as the stack pointer,
others R12.... Again on IBM because there is no PUSH/PULL one implementation
may move the stack pointer up, the other down ...

3) Then there are "helper functions". I don't think you will hit these in
Windows but on some platforms, especially those with emulated floating
point, some "C" expressions may invoke calls to "helper functions". You may
then find your self with missing routines.

Dave.
 
I

Ian Collins

Harald said:
Ian said:
Harald said:
Ian Collins wrote:

Harald van Dijk wrote:

Ian Collins wrote:

In general, on the same platform yes they can. Otherwise, how would you
link the platform's libraries?

Even on the same platform, not necessarily. The stack alignment forced
and assumed at function calls may be different, as a real-world example.

OK, I'll specialise a bit more - on most UNIX platforms (where there the
OS linker is used) they can.

Stack alignment is a compiler issue, not a linker issue. The problem is
with code as simple as

void f(void) {
int a[4] = { 0 };
}

If a compiler can assume a four word stack alignment, it may be able to
use a special instruction to zero all of a[0 ... 3] at once. If another
compiler calls f(), but simply word-aligns the stack, the special
instruction may cause a runtime abort. I'm not sure how the linker
could change this.
Well I've never seen any problems on any of the UNIX/Linux systems I
have used, after all, not matter what compiler you use, you still have
to link (and work!) with the system's libraries.

All four word-aligned stacks are also word-aligned, so if that's what
the system library assumes, no problem. The standard library would need
to use platform-specific hacks to only add multiples of 4*sizeof(int)
to the stack pointer if callback functions are used, but that's
certainly possible to do, even automatically, depending on the
compiler. I can't find a concrete example of this right now, though.

Another possibility for incompatibilities are in how large structs are
returned from functions, when the standard library only returns small
structs, or what size enum types and _Bool have, when the standard
library doesn't rely on those. Both of those are extremely easy to find
examples of, even, since GCC lets you change these (except for _Bool)
using compiler options.
All I can say is on my platform (Solaris), you would have to go out of
your way to introduce incompatibilities and your program probably
wouldn't link or run.
 

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

Forum statistics

Threads
473,774
Messages
2,569,599
Members
45,165
Latest member
JavierBrak
Top