What does flag `pIOK` mean?
Asked Answered
B

1

5

When dumping perl SV with Devel::Peek I can see:

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

But can not find the description what pIOK mean.

I tried to look it at Devel::Peek, perlapi , perlguts, perlxs ... In sources I found that:

{SVp_IOK, "pIOK,"}

But still can not find what SVp_IOK is. What is it?

UPD
I found this document. It shed the light a bit what flags mean and where they are situated. (beware this DOC is outdated a bit)

enter image description here

This flag indicates that the object has a valid non-public IVX field value. It can only be set for value type SvIV or subtypes of it.

UPD

Why private and public flags are differ

Broadnax answered 16/1, 2018 at 9:19 Comment(4)
@GerhardBarnard: If I understand right, when SV has string and this string contain integer value the SVp_IOK will be true and SV_IOK will be false, will not?Broadnax
@GerhardBarnard: Do you know the case when only one of two flags is used?Broadnax
@Gerhard: This is mostly wrong, and I don't know what you mean you mean by the lower flags.Brainstorm
@Brainstorm lower case I mean. will delete and repost as I cannot edit the comments.Mannish
B
8

pIOK is how Devel::Peek represents the bit corresponding to bit mask SVp_IOK. The p indicates a "private" flag, and it forms a pair with "public" flag IOK (bit mask SVf_IOK)

The exact meaning of the private flags has changed across perl versions, but in general terms they mean that the IV (or NV or PV) field of the SV is "inaccurate" in some way

The most common situation where pIOK is set on its own (pIOK is always set if IOK is set) is where a PV has been converted to a numeric NV value. The NV and IV fields are both populated, but if the IV value isn't an accurate representation of the number (i.e. it has been truncated) then pIOK is set but IOK is cleared

This code shows a way to reach that state. Variable $pi_str is set to a string value for π and it is converted to a floating-point value by adding 0.0 and storing it into $pi_num. Devel::Peek now shows that NOK/pNOK and POK/pPOK are set, but only pIOK while IOK remains clear. Looking at the IV value we can see why: it is set to 3, which is the cached value of int $pi_str in case we need it again, but it is not an accurate representation of the string "3.14159" in integer form

use strict;
use warnings 'all';

use Devel::Peek 'Dump';

my $pi_str = "3.14159";

my $pi_num = $pi_str + 0.0;

Dump $pi_str;

output

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 and before used to use the flag to indicate "magic" variables (such as tied values) because the value in the IV field could not be used directly. That was changed in v5.18 and later, and magic values now use pIOK in the same way as any other value

Brainstorm answered 16/1, 2018 at 12:25 Comment(4)
the SVp_IOK mask has only one bit set: 0x00001000. What do you mean: "It forms a pair?"Broadnax
that POK/pPOK and POK/pPOK are set: Do you mean that POK and pPOK are set. If so, please fixBroadnax
@EugenKonkov: I mean that IOK and pIOK are a pair. I have already said that "pIOK is always set if IOK is set" and I don't know how to write it any more clearly.Brainstorm
@Eugen: If you are so unfamiliar with perl internals then you should rely on the SvIOK(SV*) macro. It will suffice except for advanced XS code (which is already an advanced technique).Brainstorm

© 2022 - 2024 — McMap. All rights reserved.