标志'pIOK`是什么意思?

时间:2018-01-16 09:19:55

标签: perl xs perlapi

使用Devel::Peek转储perl SV时,我可以看到:

SV = IV(0x1c13168) at 0x1c13178
  REFCNT = 1
  FLAGS = (IOK,pIOK)
  IV = 2

但无法找到pIOK的含义。

我试图在Devel::Peekperlapiperlgutsperlxs查看... 在消息来源中我发现:

{SVp_IOK, "pIOK,"}

但仍无法找到SVp_IOK的内容。它是什么?

UPD
我找到了this document。它揭示了旗帜的含义以及它们所处的位置。 (要注意这个DOC已经过时了)

enter image description here

  

此标志表示该对象具有有效的非公共IVX字段值。它只能为值类型SvIV或其子类型设置。

UPD

Why private and public flags are differ

1 个答案:

答案 0 :(得分:7)

pIOKDevel::Peek表示与位掩码SVp_IOK对应的位的方式。 p表示“私有”标记,它与“公共”标记IOK形成一对(位掩码SVf_IOK

私有标记的确切含义在perl版本中已更改,但一般而言,它们表示IV(或NVPV)字段{{1}以某种方式“不准确”

SV自行设置的最常见情况(如果设置了pIOK,则始终设置为pIOKIOK已转换为数字的位置PV值。NV NVIV字段都已填充,但如果IV值不是数字的准确表示(即已被截断),则设置pIOKIOK已清除

此代码显示了达到该状态的方法。变量$pi_str设置为π的字符串值,并通过添加0.0并将其存储到$pi_num转换为浮点值。 Devel::Peek现在显示NOK/pNOKPOK/pPOK 设置,但只有pIOKIOK仍然清晰。查看IV值,我们可以看到原因:它设置为3,这是int $pi_str的缓存值,以防我们再次需要它,但它以整数形式准确表示字符串"3.14159"

use strict;
use warnings 'all';

use Devel::Peek 'Dump';

my $pi_str = "3.14159";

my $pi_num = $pi_str + 0.0;

Dump $pi_str;

输出

SV = PVNV(0x28fba68) at 0x3f30d30
  REFCNT = 1
  FLAGS = (NOK,POK,IsCOW,pIOK,pNOK,pPOK)
  IV = 3
  NV = 3.14159
  PV = 0x3fb7ab8 "3.14159"\0
  CUR = 7
  LEN = 10
  COW_REFCNT = 1

Perl v5.16之前用于使用该标志来指示“魔术”变量(例如绑定值),因为IV字段中的值无法直接使用。这在v5.18及更高版本中已更改,并且魔术值现在使用pIOK与任何其他值相同