Keeping Standard Mangling

T

Teddy

Hello,

We have our API used internally by Clients and Servers processes to
communicate each other. We want to enhance these API's so that other
Products also can communicate to us.

Problem we are facing is while linking. Other product gets undefined
symbol error due to name mangling. APIS are compiled on gcc 3.2 and we
are using gcc 3.4 while linking.

Is there any option while compilations which will ensure that Name
mangling is standard across compliers and their versions.

Thanks
 
A

Alexander Bartolich

Teddy said:
[...]
Problem we are facing is while linking. Other product gets undefined
symbol error due to name mangling. APIS are compiled on gcc 3.2 and we
are using gcc 3.4 while linking.

http://gcc.gnu.org/onlinedocs/gcc/Compatibility.html
# Starting with GCC 3.2, GCC binary conventions for C++ are based on
# a written, vendor-neutral C++ ABI that was designed to be specific
# to 64-bit Itanium but also includes generic specifications that apply
# to any platform.
# [...]
# GCC's -Wabi switch warns when G++ generates code that is probably
# not compatible with the C++ ABI.
Is there any option while compilations which will ensure that Name
mangling is standard across compliers and their versions.

The only way to go sure is

extern "C"
 
P

Pascal J. Bourguignon

Teddy said:
We have our API used internally by Clients and Servers processes to
communicate each other. We want to enhance these API's so that other
Products also can communicate to us.

Problem we are facing is while linking. Other product gets undefined
symbol error due to name mangling. APIS are compiled on gcc 3.2 and we
are using gcc 3.4 while linking.

The solution is to use the same compiler.

Is there any option while compilations which will ensure that Name
mangling is standard across compliers and their versions.

There is none, and it is even a feature: you don't want to mix C++
objects compiled with different compilers, because their fundamentally
incompatible.

To render them compatible you would have to defer some decision at
run-time (or at least, at load-time), and this is something C++
doesn't like. C++ likes to be able to commit to decisions early.



By consequence, as mentionned in the other answer, another solution is
to use C instead of C++ (at least, define your API in terms of C,
using extern "C"{ ... }). Forget about C++ classes. You may still
have an object oriented design, but using only C functions. You make
take inspiration from Objective-C or some other OO system for C.
 
P

Pascal J. Bourguignon

The solution is to use the same compiler.



There is none, and it is even a feature: you don't want to mix C++
objects compiled with different compilers, because their fundamentally
incompatible.

To render them compatible you would have to defer some decision at
run-time (or at least, at load-time), and this is something C++
doesn't like. C++ likes to be able to commit to decisions early.



By consequence, as mentionned in the other answer, another solution is
to use C instead of C++ (at least, define your API in terms of C,
using extern "C"{ ... }). Forget about C++ classes. You may still
have an object oriented design, but using only C functions. You make
take inspiration from Objective-C or some other OO system for C.


Well, later versions of gcc (eg. 4.3.4) implement name mangling
according to a "IA64 C++ ABI specification", so there may be some hope
that compilers converge toward a common ABI and therefore name
mangling. But of course, this doesn't help with respect to older
compilers. (While gcc 3.2.3 claims to implement name mangling
according to the same "IA64 C++ ABI specification", there are a few
differences...).
 
J

James Kanze

We have our API used internally by Clients and Servers
processes to communicate each other. We want to enhance these
API's so that other Products also can communicate to us.
Problem we are facing is while linking. Other product gets
undefined symbol error due to name mangling. APIS are compiled
on gcc 3.2 and we are using gcc 3.4 while linking.
Is there any option while compilations which will ensure that
Name mangling is standard across compliers and their versions.

Maybe. See your compiler docs (in particular, -fabi-version).
Note too that if g++ changed name mangling between versions, it
probably changed other things that would make the binary
representations incompatible (e.g. class layout, organization
of the vtbl, etc.). Presumably, such a change was necessary to
provide new features, and an option to revert to the old
mangling will in fact be an option to revert to the old binary
representation, and will possibly turn off or restrict some of
these new features. It's best to compile and link everything
with the same version of the compiler---with g++, with the same
build, even, since I think that there are build options which
affect the API slightly (something to do with cxa_exit, IIRC).
 
J

James Kanze

(e-mail address removed) (Pascal J. Bourguignon) writes:

[...]
Well, later versions of gcc (eg. 4.3.4) implement name
mangling according to a "IA64 C++ ABI specification", so there
may be some hope that compilers converge toward a common ABI
and therefore name mangling. But of course, this doesn't help
with respect to older compilers. (While gcc 3.2.3 claims to
implement name mangling according to the same "IA64 C++ ABI
specification", there are a few differences...).

G++ can't define any "standard" ABI conventions---that's up to
the system and the hardware architects. Most only define ABI
conventions for C, not for C++ (where things like class layout
and the structure of the vtbl are important as well). The Intel
IA64 is, in this regard, somewhat of an exception, and g++
exterpolates that specification for other platforms. At the
cost of being incompatible with other compilers for those
platforms. (But since most of the other compilers aren't
compatible with one another anyway, since most of the other
platforms don't define an ABI for C++, why not?)
 
J

Jerry Coffin

[ ... ]
the general moral of this story:
using C++ across library boundaries is absurdly brittle, and a better bet is
to not do so in the first place...

one can provide a C++ based API, but the C++ part "should" exist on the
client's end (for example, in terms of the libraries' headers), and the
actual exported interface for the library "should" be C based.

[ ... ]
partial reasons:
sharing a struct means that one side or another is inherently bound to the
current version of the struct in question, and so subtle changes to struct
layout will break code (creating versioning issues);
different compilers may follow different alignment rules (other things being
the same, member alignment tends to be variable in many cases);
different compilers rarely lay out classes exactly the same (for example,
different vtable layouts, different RTTI data, ...);
...

Essentially all of this is also true with plain C structs though...
apparently, on OS's such as Windows, each DLL ends up with a partially
disjoint heap, and so allocating things in one library and freeing them in
another is a good way to cause crashes.

That can be, but isn't necessarily the case. It depends on how the
DLL was written and (mostly) how it was compiled. It's pretty easy to
make it work by knowing what you're doing, or even just following a
few (fairly trivial) rules.
so, instead, the best option is to make the API be very "opaque"
(all operations being called via function calls, all data being
accessed via accessor functions, ...).

I can't agree. The best option is to understand what you're doing,
and program appropriately.
 
J

James Kanze

[ ... ]
[ ... ]
partial reasons:
sharing a struct means that one side or another is
inherently bound to the current version of the struct in
question, and so subtle changes to struct layout will break
code (creating versioning issues); different compilers may
follow different alignment rules (other things being the
same, member alignment tends to be variable in many cases);
different compilers rarely lay out classes exactly the same
(for example, different vtable layouts, different RTTI data,
...);
...
Essentially all of this is also true with plain C structs
though...

Except that almost all platforms define a C ABI, which all
compilers respect, since otherwise, system calls wouldn't work.

The only platform I know of off hand that defines a C++ ABI is
the IA64.
That can be, but isn't necessarily the case. It depends on how
the DLL was written and (mostly) how it was compiled. It's
pretty easy to make it work by knowing what you're doing, or
even just following a few (fairly trivial) rules.

I'm not sure, but I think the linking plays a role as well; if
you link with the dynamic crt, you don't have problems. (At
least, I've never had problems doing this.)
 

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
474,159
Messages
2,570,879
Members
47,414
Latest member
GayleWedel

Latest Threads

Top