Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?
 
PerlMonks  

Name conflict between MinGW C++ standard library header and Perl development header

by llancet (Friar)
on Nov 11, 2014 at 05:52 UTC ( [id://1106773]=perlquestion: print w/replies, xml ) Need Help??

llancet has asked for the wisdom of the Perl Monks concerning the following question:

My project compiles OK on several Linux platforms. But when I compile it under windows, it claims the following error:

In file included from D:/Strawberry-5.20.1.1-ia32/c/i686-w64-mingw32/i +nclude/c++/iostream:39:0, from D:/mydoc/projects/GenoEye-0.4.5-Source/src/genoe +ye/Common.h:9, from D:\mydoc\projects\GenoEye-0.4.5-Source\perl\geno +eye_perl.h:9, from D:\mydoc\projects\GenoEye-0.4.5-Source\perl\geno +eye_perl.cpp:1: D:/Strawberry-5.20.1.1-ia32/c/i686-w64-mingw32/include/c++/ostream:335 +:49: error: macro "PerlLIO_write" requires 3 arguments, but on ly 2 given write(const char_type* __s, streamsize __n);

This is the content around ostream line 335:

/** * @brief Character string insertion. * @param __s The array to insert. * @param __n Maximum number of characters to insert. * @return *this * * Characters are copied from @p __s and inserted into the stre +am until * one of the following happens: * * - @p __n characters are inserted * - inserting into the output sequence fails (in this case, ba +dbit * will be set in the stream's error state) * * @note This function is not overloaded on signed char and * unsigned char. */ __ostream_type& write(const char_type* __s, streamsize __n);

and this is the beginning of genoeye_perl.h, which includes both Perl headers and C++ headers:

extern "C" { #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" } #include <genoeye/Common.h> #include <genoeye/Page.h> #include <genoeye/Frame.h> #include <genoeye/Track.h> #include <genoeye/Segment.h> #include <genoeye/Elem.h> #include <genoeye/Block.h> #include <genoeye/Tag.h> #include <genoeye/Chart.h> #include <genoeye/HomologRegion.h> #include <genoeye/ElemConnect.h>

the "write" function declaration is probably conflict with Perl's internal definition. How can I solve this problem?

I'm using the MinGW toolchain provided with strawberry perl 5.20.1.1. This issue also occurs with older versions of strawberry perl.

------

Pretty sad, simply undefine the Perl-induced macro don't work

extern "C" { #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" } #undef write #include <genoeye/Common.h> ......

This does not change anything. This is very suprise.

Replies are listed 'Best First'.
Re: Name conflict between MinGW C++ standard library header and Perl development header
by syphilis (Archbishop) on Nov 11, 2014 at 07:12 UTC
    The problem is that XSUB.h contains:
    #define write PerlLIO_write
    What happens if you #include the genoeye headers *before* XSUB.h gets included ?

    Another thing you could try is to undef write prior to #including the genoeye headers:
    #ifdef write #undef write #endif #include <genoeye/Common.h> #include <genoeye/Page.h> ....
    And the *other* thing you could try is to wait for better advice ;-)

    Cheers,
    Rob

      And the *other* thing you could try is to wait for better advice ;-)

      Naw, I like this advice. I almost posted something similar, because I have also found that it is sometimes useful to #undef away a macro conflict in these situations. It's a good suggestion (unless it doesn't work). I hesitated in posting the thought because I figured someone would have a better idea. ;)


      Dave

        Is the idea of loading the genoeye headers *before* loading the perl headers likely to be helpful ?
        It certainly breaks the conventional way of doing things (and I don't think I've ever tried it), but it's probably the safest solution ...... if it works.

        Cheers,
        Rob
      Why I don't got this issue while compiling same code under Linux?
        Why I don't got this issue while compiling same code under Linux?

        Does "write" get defined to PerlLIO_write for you in Linux ?
        use strict; use warnings; use Inline C => <<'EOC'; int foo() { #ifdef write return 1; #else return 0; #endif } EOC print foo();
        All Inline::C scripts automatically load XSUB.h - hence no need to specifically #include that header.
        That script outputs 1 for me on Windows, but 0 for me on Debian Wheezy.

        Cheers,
        Rob
      It does not work. The same error occurs... That is pretty suprising: why I undef the macro, but it is still seen by latter code?
        The same error occurs

        It shouldn't be *exactly* the same error. I think
        D:\mydoc\projects\GenoEye-0.4.5-Source\perl\genoeye_perl.h:9
        should have become:
        D:\mydoc\projects\GenoEye-0.4.5-Source\perl\genoeye_perl.h:11
        Otherwise the modified file was not found.

        Cheers,
        Rob

      The issue is located to perl.h, not XSUB.h:

      #include "perl.h" #include <iostream> int main() { std::cout << "foo" << std::endl; }
      and compile with:
      D:\mydoc\projects\GenoEye-0.4.5-build\perl>g++ -ID:/gtk+-2.24.10/inclu +de/cairo -ID:/gtk+-2.24.10/include/glib-2.0 -ID:/gtk+-2.24.10/ lib/glib-2.0/include -ID:/gtk+-2.24.10/include -ID:/gtk+-2.24.10/inclu +de/freetype2 -ID:/gtk+-2.24.10/include/libpng14 -ID:/mydoc/pro jects/GenoEye-0.4.5-Source/src -ID:/mydoc/projects/GenoEye-0.4.5-build +/src -ID:/mydoc/projects/GenoEye-0.4.5-Source -ID:/Strawberry- 5.20.1.1-ia32/perl/lib/CORE -ID:/mydoc/projects/GenoEye-0.4.5-Source/p +erl -g -o test.exe test.cpp

      it will reproduce this issue. Also, add #undef write before #include <iostream> won't help.

      However, this conflict do not reproduce if I use Inline::CPP. The code below works well:

      use strict; use Inline 'CPP' => config => BUILD_NOISY => 1, INC => '-ID:/mydoc/projects/GenoEye-0.4.5-Source/src -ID:/mydoc/p +rojects/GenoEye-0.4.5-Source/perl -ID:/gtk+-2.24.10/include/cairo'; foobar(); use Inline 'CPP' => <<'CODE'; #include <perl.h> #include <iostream> void foobar() { std::cout << "foobar" << std::endl; } CODE
      Why there's such big difference? I cannot understand it...
        Why there's such big difference? I cannot understand it...

        (Yeah ... sorry, not much point running Inline::C scripts when we're dealing with something that's specific to Inline::CPP ;-)

        I don't grok C++, and I can only assume that in your simplified Inline::CPP script, the write() call in ostream has not been made visible. It's definite that 'write' has been defined to 'PerlLIO_write' - just try to use write() in your Inline::CPP script and you'll be able to verify:
        use strict; use Inline 'CPP' => config => BUILD_NOISY => 1; foobar(); use Inline 'CPP' => <<'CODE'; #include <perl.h> // not needed - gets included automatically #include <iostream> void foobar() { std::cout << "foobar" << std::endl; } void break_me(SV * a, SV * b) { write(a, b); } CODE
        That generates the error:
        try_pl_dec5.xs:28:14: error: macro "PerlLIO_write" requires 3 argument +s, but only 2 given write(a, b);
        In ostream, the write() declaration is preceded (next line up) by __ostream_type&. I don't know whether that puts aome sort of condition upon whether the function is visible or not.
        Maybe if you include the same headers in the compilation of your Inline::CPP script as were used for the C++ script then things might start to add up correctly.

        I know it's messy ... XS is like that, but you just have to work through it.

        Cheers,
        Rob

        Why there's such big difference? I cannot understand it...

        Um, Inline generates XS, look at it and note the differences, right?

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1106773]
Approved by atcroft
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others making s'mores by the fire in the courtyard of the Monastery: (7)
As of 2024-04-23 15:02 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found