Hi,
Hidden below my sig (by readmore tags) is a full Inline::C script that demos the problem. It uses overload, so that the subroutine 'overload_add_eq' is invoked whenever a '+=' is applied to the blessed object. At one stage, 'overload_add_eq' looked like this:
SV * overload_add_eq(SV * obj, SV * addon, SV * third) { Card* c = (Card *)SvIV(SvRV(obj)); SvREFCNT_inc(obj); c->value += SvIV(addon); return obj; }
And that works fine - but it occurred to me that I should be able to rewrite the function as in 'in place' operation (ie one that did not return anything) so I rewrote it as:
void overload_add_eq(SV * obj, SV * addon, SV * third) { Card* c = (Card *)SvIV(SvRV(obj)); c->value += SvIV(addon); }
Now, when I do $obj += $addon; windows intervenes to tell me that perl.exe has stopped working (but fails to come up with any other information). On linux I get a segfault. Interestingly, I find that this modified 'overload_add_eq' works fine (on both linux and windows) when invoked explicitly in perl code as overload_add_eq($obj, $addon, 0);. It's only when it's invoked by the overload mechanism that the problem arises. Anyone know why that is, and what to do about it ?

Cheers,
Rob
use warnings; package My_struct; use Inline (C => Config => BUILD_NOISY => 1, ); use Inline C => <<'EOC'; typedef struct { char * suit; int value; } Card; SV * create_struct(SV * s, SV * v) { Card * cptr; New(123, cptr, sizeof(Card), Card); if(cptr == NULL) croak("Failed to allocate memory in create_struc +t function"); cptr->suit = SvPV_nolen(s); cptr->value = SvIV(v); return sv_setref_pv(newSViv(0), "My_struct", cptr); } void deref_ref(SV * obj) { Inline_Stack_Vars; Inline_Stack_Reset; Inline_Stack_Push(newSVpv(((Card *)SvIV(SvRV(obj)))->suit, 0)); Inline_Stack_Push(newSViv(((Card *)SvIV(SvRV(obj)))->value)); Inline_Stack_Done; Inline_Stack_Return(2); } void DESTROY(SV * obj) { printf("Destroying ..."); Card* c = (Card *)SvIV(SvRV(obj)); Safefree(c); printf("...destroyed\n"); } void overload_add_eq(SV * obj, SV * addon, SV * third) { Card* c = (Card *)SvIV(SvRV(obj)); // SvREFCNT_inc(obj); c->value += SvIV(addon); // return obj; } EOC use overload '+=' => \&overload_add_eq; $suit = ('Hearts', 'Spades', 'Clubs', 'Diamonds')[rand(4)]; $value = int(rand(13)) + 1; $obj = create_struct($suit, $value); $addon = 5; @members = deref_ref($obj); print "@members\n"; #$obj += $addon; # Crashes overload_add_eq($obj, $addon, 0); @members = deref_ref($obj); print "@members\n";

In reply to Overload '+=' with XSub by syphilis

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.