3

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

  • sv_setref_iv()将其IV参数存储在IV插槽中,
  • sv_setref_nv()将其NV参数存储在NV插槽中,
  • 但是sv_setref_pv()将其void *参数存储在IV插槽中,而不是PV插槽中?

我有一种预感(CUR 和 LEN 字段对于这样的变量没有意义),但我想听听懂 XS 的人的意见 :-)

4

1 回答 1

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 个字节。

于 2014-02-10T14:04:00.150 回答