Edward
Edward

Reputation: 486

Why does sv_setref_pv() store its void * argument in the IV slot?

When looking at the Perl API, I was wondering why

I have a hunch (the CUR and LEN fields wouldn't make sense for such a variable), but I'd like to have the opinion of someone knowledgeable in XS :-)

Upvotes: 3

Views: 257

Answers (1)

ikegami
ikegami

Reputation: 386311

There are many different types of scalars.

  • SvNULL isn't capable of holding any value except undef.
  • SvIV is capable of holding an IV, UV or RV.
  • SvNV is capable of holding an NV.
  • SvPV is capable of holding a PV.
  • SvPVIV is capable of holding a PV, as well as an IV, UV or RV.
  • ...

AV, HV, CV, GV are really just types of scalar too.

Note I said "capable" of holding. You can think of scalars as being objects, and the above as being classes and subclasses. Each of the above has a different structure.

Having these different types of scalars allows one to save memory.

An SvIV (the smallest scalar type capable of holding an IV) is smaller than an SvPV (the smallest scalar type capable of holding a PV).

$ perl -le'
   use Devel::Size qw( total_size );

   use Inline C => <<'\''__EOI__'\'';

      void upgrade_to_iv(SV* sv) {
         SvUPGRADE(sv, SVt_IV);
      }

      void upgrade_to_pv(SV* sv) {
         SvUPGRADE(sv, SVt_PV);
      }

__EOI__

   { my $x; upgrade_to_iv($x); print total_size($x); }
   { my $x; upgrade_to_pv($x); print total_size($x); }
'
24
40

Using an SvIV instead of an SvPV is a savings of 16 bytes per reference.

Upvotes: 6

Related Questions