Will this work for you?

#ifdef __cplusplus
extern "C" { extern int Perl___notused(void); }
#else
extern int Perl___notused(void);
#endif

#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;
}

On May 4, 2012, at 11:59 AM, Craig A. Berry wrote:

> 
> On May 4, 2012, at 11:57 AM, Craig A. Berry wrote:
> 
>> 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;
> 
> Bah, copy and paste error.  There should be two more lines right here like so:
> 
>  int j = Perl___notused();
> }
> 
>> $ 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
>> 
> 
> ________________________________________
> 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