ExtUtils::ParseXS can generate invalid C++

[email protected] (David Oswald)
Newsgroups perl.xs,perl.inline
Message-ID <CAKTcQ96ZT-9CUNHuF44RU9eOb+tOr3eVCwSSafhdg=p2d+1hwQ@mail.gmail.com>
[ This message is being sent to [email protected] seeking suggestions,
with a CC to [email protected] as an FYI. ]

We have a situation with Inline::CPP wherein the module is failing to
pass smoke testing when the compiler is g++ version 4.4.3 (though I
think the issue probably goes back to 4.2.1).  Here is an example of
two failure reports:

http://www.cpantesters.org/cpan/report/35702916-59fc-11e1-8417-42773f40e7b5
http://www.cpantesters.org/cpan/report/afd08dc8-59fb-11e1-8417-42773f40e7b5

The CPAN Testers Results Overview (statistical analysis) shows a
strong correlation between g++ v4.4.3 and failure.
http://analysis.cpantesters.org/solved?distv=Inline-CPP-0.34_002#conf%3Agccversion

The error message that I think is most relevant from those reports
looks like this:

_01basic_t_5cd2b57.c:212: error: invalid use of ‘static’ in
linkage specification

There will be many of these messages -- one for each C++ function (or
object method in this case) that fails to compile.  As I've
investigated a possible reason for this I keep bumping into
explanations (on StackOverflow, Usenet, etc.) that there cannot be two
storage class specifiers for any given function.  In other words, in
"Standard C++", you cannot have:

extern "C" void static mysub ( int something );

Because both 'extern "C"' and 'static' are storage class specifiers.
One workaround is this:

extern "C" { void static mysub ( int something ); }

Now frankly I don't know EU::ParseXS's code well at all, and haven't
walked through it.  But it seems like it probably should be wrapping
static functions in an

extern "C" { ...... }

block rather than just prepending

extern "C"

The question might come up "Why are only two of a couple hundred smoke
tests failing on this issue?"  I think that the answer is that
starting with g++ v4.1.2 this aspect of "Standard" C++ began to be
enforced.  I can't find any command-line flags to disable it, but it
seems that it's a problem that will probably get worse as more g++
users migrate to newer versions.  That said, I'm actually using a
4.4.x version of g++ on one of my systems and cannot duplicate the
failure... bad luck for me, I guess; I'd really like to personally get
my hands on a failure so that I can try to fix it locally first.

It's entirely possible that I'm barking up the wrong tree.  When using
Inline::CPP there are many layers involved that separate user code
from final product.  Inline::CPP subclasses Inline::C, and uses Inline
(as does Inline::C).  They rely on Parse::RecDescent, and Inline
relies on ExtUtils::ParseXS.  It's possible I've missed something in
Inline::CPP's code, or in how Inline::C and Inline deal with the
Inline::CPP.  But there's one module that is ultimately connected with
the .c output from the .xs output of Inline, and that's EU::ParseXS,
and that module is the one generating the actual 'extern "C"' linkage
modifier, so here I am.

If anyone has any idea on what should happen next... whether
EU::ParseXS needs some help, or whether I should be digging more into
Inline::CPP and Inline's source, I'd appreciate some suggestions.

Dave Oswald

-- 

David Oswald
[email protected]
[email protected]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.