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:[email protected]
"... getting out of a sonnet is much more
difficult than getting in."
Brad Leithauser