in reply to Re: GIMME_V==G_ARRAY anomaly on win32 (5.10 only)
in thread GIMME_V==G_ARRAY anomaly on win32 (5.10 only)

the only possibility that crosses my mind is that the internal representation of boolean true/false varies between the two compilers somehow

The thing is that there's only *one* compiler. Irrespective of whether I compile the script with ActivePerl or MinGW-built perl, it's the one and same (gcc-3.4.5) compiler that's doing the compilation.
Admittedly that's not the compiler that actually *built* ActivePerl, but it does use the same CRT as the compiler that built ActivePerl - which is one reason that I expect to *not* be confronted with this sort of problem :-)

The more I think about it, the weirder it seems. I'll play around with it myself a little more today, and then maybe post to p5p as ikegami suggests. I'm a little hesitant to post there as the description of what I'm doing and how to run the demo is somewhat messy - even though what I'm doing is really quite straight forward.
Maybe I can clean the description up a little.

Thanks for the thoughts - and please don't hesitate to present any others you may have. I've added your 2 printf() calls to the script in case they provide some help somewhere down the track.

Cheers,
Rob
  • Comment on Re^2: GIMME_V==G_ARRAY anomaly on win32 (5.10 only)

Replies are listed 'Best First'.
Re^3: GIMME_V==G_ARRAY anomaly on win32 (5.10 only)
by almut (Canon) on Dec 19, 2009 at 01:15 UTC
    Admittedly that's not the compiler that actually *built* ActivePerl, ...

    My speculation would be that this is the problem (but I don't have the prerequisites here to try).  GIMME_V is a rather complex macro which accesses code in the perl binary (without using the CRT, so it's irrelevant that the CRT is the same). G_ARRAY, OTOH, is a simple constant that gets compiled directly into the extension DLL. In other words, you are mixing code compiled with different compilers, but if you recompile, the macro presumably is being expanded appropriately...

      My speculation would be that this is the problem (but I don't have the prerequisites here to try).

      Seems reasonable - and it may be *part* of the problem, but I feel there's gotta be more to it than that.
      Presumably GIMME_V is also a complex macro in 5.8.x, yet there's no such problem there. I guess that some change in GIMME_V between 5.8 and 5.10 has triggered the event. I'm a little curious as to whether that change constitutes a bug.
      Also, note that there's no problem using this "foreign" MinGW compiler with ActivePerl. The problem arises only when binaries (involving GIMME_V) built on MinGW-built perl are installed onto ActivePerl (and vice-versa). Everything is sweet if the binaries installed on ActivePerl are compiled using ActivePerl and MinGW.

      So ... I guess we're also looking at some difference between the 2 perl dll's themselves. I'm of the uninformed opinion that such a difference ought *not* exist - which is just another way of saying "I don't know whether it's right that such a difference should exist, but I'd prefer it not to be".

      Thanks for your input.

      Cheers,
      Rob
        Presumably GIMME_V is also a complex macro in 5.8.x, yet there's no such problem there.

        It's not the complexity per se, but rather the specifics of what happens in detail. And just because it works with 5.8 does not necessarily imply it would have to work with 5.10, too. A minor change could be sufficient to cause different behaviour.

        For one, compilers generate machine code based on implicit assumptions with respect to their inner workings (like widths of data types, alignment of fields within structs, etc.). If you mix machine code compiled with different compilers, the underlying assumptions may or may not match. Often, there is no problem, but there's no guarantees whatsoever.  OTOH, the same compiler can also generate different code depending on the build environment, such as compiler options, contents of header files involved, etc. — which would explain why when recompiling with the same compiler, but in the context of a different Perl (MinGW-built Perl vs. default ActivePerl), everything is sweet.

        I bet that if you use a debugger to step through the machine code behind that GIMME_V macro, you'll figure out why it evaluates to 0x80 (== G_VOID, btw), instead of 1 (== G_ARRAY), in the problem case.

Re^3: GIMME_V==G_ARRAY anomaly on win32 (5.10 only)
by BrowserUk (Patriarch) on Dec 19, 2009 at 00:15 UTC
    but it does use the same CRT as the compiler that built ActivePerl

    My final speculation. Does this change anything?

    use warnings; use Inline C => Config => BUILD_NOISY => 1; use Inline C => <<'EOC'; int junk( int val ) { return printf( "%d\n", val ); } void foo() { junk( GIMME_V == G_ARRAY ); } EOC my $x = [foo()];

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      Does this change anything?

      Unfortunately, no :-)

      Cheers,
      Rob
Re^3: GIMME_V==G_ARRAY anomaly on win32 (5.10 only)
by ikegami (Patriarch) on Dec 18, 2009 at 23:20 UTC
    What's the result matrix for
    void foo() { printf("%x\n", GIMME_V); printf("%x\n", G_ARRAY); printf("%d\n", GIMME_V == G_ARRAY); }

    Maybe it would help if you posted the generated C and XS files for each Perl. They normally get deleted, but you can avoid that with

    perl -MInline=NOCLEAN,force script.pl

    ( "force" forces a rebuild )

      ( "force" forces a rebuild )

      Everything works fine if I do a rebuild. It's only when I run MinGW-built binaries on ActivePerl or ActivePerl-built binaries on MinGW perl that the problem arises (even though it's the exact same compiler building the binaries, irrespective of which perl is being used.) When I run the "foreign" binary on the "perl that didn't build the binary", GIMME_V inevitably returns G_VOID (afaict).

      Now some people may raise eyebrows at the practice of throwing binaries around like I'm doing - but it's something I've been doing for quite some time without any troubles at all. I don't see why it should pose a problem, until now I've been quietly confident it would never pose a problem, it's still *not* a problem on perl-5.8.x, but all of a sudden I find that I can't do it on 5.10.x when an XSub relies on GIMME_V.

      I'm hoping it's a bug - but even if it is, I may have trouble convincing the people that count :-)
      Then again, fairk, I may have been indulging in a bad pratice for all these years, after all. If so, then the implication is that you must provide separate binaries for Strawberry Perl (or any MinGW-built perl) and ActivePerl - which is probably not such a big deal since Strawberry users aren't generally interested in binaries anyway, but it's interesting nonetheless.

      I actually provide a few ppm packages (including Net-SSH2) to the uwinnipeg rep - all built using the MinGW compiler. In the past, I haven't paid much attention to whether I built the packages with ActivePerl or with my own MinGW-built perl. But it now looks like I ought to make sure that I build them using ActivePerl.

      The result matrices for the code you posted are:
      1) For the perl 5.10.x that compiles the script:
      1 1 1
      2) For the "other" perl 5.10.x:
      80 1 0
      No matter which perl builds the script, the generated XS and C files are identical. (These files are reproduced below my sig in the <readmore> section.)

      Cheers,
      Rob
        Using gcc version 3.4.5 (mingw-vista special r3) I get
        1 1 1
        on strawberry v5.10.0, self built 5.10.1 , and activeperl v5.8.9 Build 825 288577

        The XS looks identical to yours and doesn't change between the 3 perls

        Grepping the CORE directory I get in all 3 perls

        CORE/cop.h:#define G_ARRAY 1 lib\CORE/op.h:#define GIMME_V OP_GIMME(PL_op, block_gim +me())
        but on bleadperl I see #define G_ARRAY 3