I've been taking a swing at compiling Perl with the HP C++ compiler for 
OpenVMS.[1]  There are a number of wrinkles to iron out, one of which boils 
down to:

$ type try.c
#define dNOOP extern int Perl___notused(void)
#define XSPROTO(name) void name(void)
#define XS(name) extern "C" XSPROTO(name)

void func1(void) {
  dNOOP;
  int i = Perl___notused();
}

XS(func2) {
  dNOOP;

$ cxx try.c

  dNOOP;
..^
%CXX-E-INCLNKSPE, linkage specification is incompatible with previous
          "Perl___notused" (declared at line 6)
at line number 11 in file D0:[craig.blead]TRY.C;30

%CXX-I-MESSAGE, 1 error detected in the compilation of 
"D0:[craig.blead]TRY.C;30".

The macros in this test file have been patched together from what's in XSUB.h 
and perl.h as seen when __cplusplus is defined.  The dNOOP macro means "don't 
do anything" and usually appears as an expansion of dVAR, which means "don't do 
anything unless threads are enabled."  For real-world examples, look in mro.c, 
perlio.c, etc.

What the compiler is whingeing about is that we've asked for two versions of 
the external symbol "Perl___notused," one that is name mangled, and one 
(because it's inside 'extern "C"' via the XS macro via the XSPROTO macro) that 
is not mangled.  And it's not just saying it's bad taste: it's throwing an 
error, not a warning.  Of course we don't *care* because "notused' means we 
aren't going to use it, and are just faking so it looks like we're doing 
something when we aren't, but the compiler doesn't know that.  

In my example I've inserted function calls to Perl___notused() so I can see 
what symbol names the compiler is actually generating, but removing those 
function calls (which corresponds more closely to the real-world build) doesn't 
make the error go away.

Other C++ compilers seem to silently create two different, unrelated symbols 
from the same token without so much as a warning. For example, g++ clearly 
shows us getting one mangled and one unmangled version of the symbol:

% g++ -g -S -c try.c
% grep notused try.s
        call    __Z14Perl___notusedv
        call    _Perl___notused
        .ascii "_Z14Perl___notusedv\0"
        .ascii "Perl___notused\0

I'm rather stumped about what to do.  Any suggestions?

[1]  Getting the build to work with C++ has been on the to-do list for over a 
decade.  One of the developments in that time period is that on Itanium, the 
backend for the C++ compiler is some gadget from Intel that is unrelated to and 
purportedly generates much faster IA64 code than the traditional GEM compiler 
backend for VMS that was ported from VAX to Alpha to IA64.
________________________________________
Craig A. Berry
mailto:craigbe...@mac.com

"... getting out of a sonnet is much more
 difficult than getting in."
                 Brad Leithauser

Reply via email to