为什么sv_setref_pv()将其void *参数存储在IV插槽中?

时间:2014-02-10 13:38:09

标签: perl xs

在查看Perl API时,我想知道为什么

  • sv_setref_iv()IV参数存储在IV广告位
  • sv_setref_nv()NV参数存储在NV广告位
  • 但是sv_setref_pv()void *个参数存储在IV广告位中,而不是PV广告位?

我有预感(CUR和LEN字段对于这样的变量没有意义),但我想得到XS知识渊博的人的意见: - )

1 个答案:

答案 0 :(得分:6)

有许多不同类型的标量。

  • SvNULL除了undef之外不能保留任何值。
  • SvIV能够持有IV,UV或RV。
  • SvNV能够持有NV。
  • SvPV能够持有PV。
  • SvPVIV能够持有PV,以及IV,UV或RV。
  • ...
AV,HV,CV,GV也只是标量的类型。

注意我说"有能力"持有。您可以将标量视为对象,将上述视为类和子类。上述每一种都有不同的结构。

拥有这些不同类型的标量可以节省内存。

SvIV(能够容纳IV的最小标量类型)小于SvPV(能够容纳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

使用SvIV而不是SvPV可以节省每个引用16个字节。