All of Perl's data structures support magic, not just SV
s (despite the name) and specifically for hashes and arrays this is the basis for things like the tie
mechanism or things like fieldhash
which implements an analogue of weak references at the level of hash entries.
Since the OUTPUT
directive indicates which arguments would presumably be modified by the C body of the XSUB, and a variable containing set magic might be passed in, setting the value as per the typemap without invoking the set handler may result in inconsistent behaviour.
use Scalar::Util qw(weaken);
my $foo;
my $ref = \$foo;
weaken($ref);
As an example of magic, weaken
decrements the reference count of $foo
, and adds magic pointing back to $ref
so that it is cleared it when $foo
gets garbage collected.
Additionally, it also adds set magic to $ref
, to tear down this back referencing, otherwise when $foo
is destroyed, $ref
would be cleared even though at this point it's no longer pointing at $foo
.
If you use $ref as an argument, it gets aliased on the stack (which is why $_[0]
is assignable):
modifies_arguments($ref);
sub modifies_arguments {
$_[0] = "blah"; # set magic is invoked to tear down the back referencing
}
If modifies_arguments
is a pure Perl it's easy to see why this is appropriate, but the same assumptions about correctness must of course hold for XSUBs, which is why OUTPUT
is used to mark which arguments will have their value set to whatever the C level argument variable had at the end of the function body, and have set magic triggered.
This does not apply to RETVAL
, since that is not technically an assignment, but rather pushing a new SV onto the stack, and any set magic will be handled after the function returns by the assignment op (if any).
"needed for hash or array element parameters that must be created if they didn't exist"
? What does this refer to? Does it mean thatset
magic is not applied to scalars or something else? – Passbook