in reply to XS/Inline::C concat *any* two SVs.
As for the "Attempt to free unreferenced scalar" warning, you can avoid that one of two ways.
You have to decide whether your XS algorithm is the equivalent of $a .= $b or $a = $a . $b. If there's a possibility that $a might be read-only, then your only choice is $a = $a . $b.
If you want $a .= $b, then your Inline C function should be a void function rather than returning an SV*. If you want $a = $a . $b, then you need to create a new scalar and return it.
You should not ever return the SAME scalar that was passed in. Right now, the scalar is having its reference count dropped twice -- once when you leave the XS function, and once when @_ is cleaned up after that function returns. That's why you have to increment it to avoid the freeing error. But you shouldn't do it that way -- you should either return a new scalar, or void.
Since you want the impossible (appending to read-only scalars), I can't supply a script which solves your problem, but here's one that hopefully points the way:
#!/usr/bin/perl use strict; use warnings; use Inline C => <<'END_C'; SV* concat(SV *a, SV *b) { SV *c; if (SvOK(a)) c = newSVsv(a); else c = newSVpvn("", 0); if (SvOK(b)) sv_catsv(c, b); return c; } void append(SV *a, SV *b) { if (!SvOK(a)) sv_setpvn(a, "", 0); if (SvOK(b)) sv_catsv(a, b); } END_C my @pairs = ( [ 'bill', undef ], [ 'bill', 'fred' ], [ undef, 'fred' ], [ 1, undef ], [ 1, 1 ], ); test($_) for @pairs; sub test { my $pair = shift; my $c = concat(@$pair); print "$c\n"; append(@$pair); print "$pair->[0]\n"; }
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: XS/Inline::C concat *any* two SVs.
by BrowserUk (Patriarch) on May 28, 2006 at 15:39 UTC | |
by dragonchild (Archbishop) on May 29, 2006 at 02:21 UTC | |
by BrowserUk (Patriarch) on May 29, 2006 at 04:12 UTC | |
by vkon (Curate) on May 28, 2006 at 22:13 UTC | |
|
Re^2: XS/Inline::C concat *any* two SVs.
by BrowserUk (Patriarch) on May 30, 2006 at 06:38 UTC | |
by creamygoodness (Curate) on May 30, 2006 at 14:06 UTC | |
by BrowserUk (Patriarch) on May 30, 2006 at 15:25 UTC | |
by creamygoodness (Curate) on May 30, 2006 at 16:00 UTC | |
by BrowserUk (Patriarch) on May 30, 2006 at 17:53 UTC | |
|