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])

Reply via email to