develooper Front page | perl.perl5.porters | Postings from May 2012

C++, XS, and dNOOP, or Doing Nothing is Hard Work

Thread Next
Craig A. Berry
May 4, 2012 09:57
C++, XS, and dNOOP, or Doing Nothing is Hard Work
Message ID:
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) {
  int i = Perl___notused();

XS(func2) {

$ cxx try.c

%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

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

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About