We ran into a problem building KDE on HP-UX 11.23/IA with the HP C++
compiler. The compiler mangled a function name in a .cpp file though
it was declared extern "C" in the .h file. After a post to the HP C++
developers list, we were told this behavior is correct. GCC 4.0.2 does
not do this so I'd like to get your opinion.
$ cat mangle-1.cc
typedef enum {
XSLDBG_MSG_THREAD_NOTUSED,
XSLDBG_MSG_THREAD_INIT
} XsldbgMessageEnum;
extern "C" {
void xsldbgSetAppFunc (int (*notifyXsldbgAppFunc) (XsldbgMessageEnum type,
const void *data));
}
static int (*notifyXsldbgAppFuncPtr) (XsldbgMessageEnum type,
const void *data) = 0;
void xsldbgSetAppFunc (int (*notifyXsldbgAppFunc) (XsldbgMessageEnum type,
const void *data))
{
notifyXsldbgAppFuncPtr = notifyXsldbgAppFunc;
}
$ g++ --version
g++ (GCC) 4.0.2 (TWW)
Copyright (C) 2005 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE.
$ g++ -c mangle-1.cc
$ nm mangle-1.o | grep -i xsldbg
0000000000000000 b notifyXsldbgAppFuncPtr
0000000000000000 T xsldbgSetAppFunc
So, GCC isn't mangling it. Now for the HP C++ compiler:
[HP-UX 11.23/IA]
$ aCC -AA -c mangle-1.cc
# nm mangle-1.o | grep -i xsldbg
[9] | 0| 48|FUNC |GLOB |0|
.text|_Z16xsldbgSetAppFuncPFi17XsldbgMessageEnumPKvE
Let's try some other compilers:
[Solaris 8]
$ CC -V
CC: Sun C++ 5.5 Patch 113817-15 2005/10/25
$ CC -c mangle-1.cc
"mangle-1.cc", line 15: Warning: function void(int(*)(XsldbgMessageEnum,const
void*)) overloads extern "C" void(extern "C" int(*)(XsldbgMessageEnum,const
void*)) because of different language linkages.
1 Warning(s) detected.
$ nm mangle-1.o | grep -i xsldbg
[4] | 16| 36|FUNC |GLOB |0 |2
|__1cQxsldbgSetAppFunc6FpFnRXsldbgMessageEnum_pkv_i_v_
[3] | 0| 4|OBJT |LOCL |0 |3 |notifyXsldbgAppFuncPtr
[IRIX 6.5]
$ CC -version
MIPSpro Compilers: Version 7.4.4m
$ CC -c mangle-1.cc
$ nm mangle-1.o | grep -i xsldbg
[3] | 0| 40|FUNC |GLOB |DEFAULT |5 |xsldbgSetAppFunc
[16] | 0| 0|STAT |LOCL |DEFAULT
|MIPS_DATA|notifyXsldbgAppFuncPtr
[AIX 5.3]
$ xlC -c mangle-1.cc
$ nm mangle-1.o | grep -i xsldbg
.xsldbgSetAppFunc T 0
xsldbgSetAppFunc D 88 12
xsldbgSetAppFunc d 80 4
[Tru64 UNIX 5.1]
$ cxx -version V7.1-006 -V
Compaq C++ V7.1-006 for Compaq Tru64 UNIX V5.1 (Rev. 732)
Compiler Driver V7.1-006 (cxx) cxx Driver
$ cxx -version V7.1-006 -c mangle-1.cc
$ nm mangle-1.o | grep -i xsldbg
xsldbgSetAppFunc(int (*)(XsldbgMessageEnum, const void*)) | 0000000000000000
| T | 0000000000000008
So, it looks like the HP-UX/IA, Sun, and Tru64 UNIX C++ compilers
mangle but the AIX, SGI, and GNU C++ compilers do not.
Fixing mangle-1.c for HP, Sun, and Tru64 UNIX is easy (after the HP
developer told me how to do it):
$ cat mangle-2.cc
typedef enum {
XSLDBG_MSG_THREAD_NOTUSED,
XSLDBG_MSG_THREAD_INIT
} XsldbgMessageEnum;
typedef int (*notifyXsldbgAppFuncType) (XsldbgMessageEnum type,
const void *data);
extern "C" {
void xsldbgSetAppFunc (notifyXsldbgAppFuncType notifyXsldbgAppFunc);
}
static notifyXsldbgAppFuncType notifyXsldbgAppFuncPtr = 0;
void xsldbgSetAppFunc (notifyXsldbgAppFuncType notifyXsldbgAppFunc) {
notifyXsldbgAppFuncPtr = notifyXsldbgAppFunc;
}
According to the HP developer:
>This is a subtle one that we see fairly often. The problem is that
>there are two functions xsldbgSetAppFunc with different types. The
>first (the declaration) has a parameter of type
>
>*notifyXsldbgAppFunc) (XsldbgMessageEnum type, const void *data)
>
>and that parameter has C linkage. The second (the definition, which
>ends up being mangled) has a parameter of type:
>
>*notifyXsldbgAppFunc) (XsldbgMessageEnum type, const void *data)
>
>but that parameter has C++ linkage. Since this is recognized as a
>different function because of the difference in parameter, and is not
>itself enclosed in an extern "C" block, it is mangled.
>
>To get these to match, you need to define a type for the parameter
>which has C linkage and use it in both places, or place the entire
>definition in an extern "C" block, if that will fork for your actual
>situation.
>The linkage of a parameter that is a function is considered in its type.
>One has C linkage, the other C++ linkage. It is subtle.
Who is right?
--
albert chin ([EMAIL PROTECTED])