Что означает флаг `pIOK`?

При сбросе Perl SV с Devel::Peek Я могу видеть:

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

Но не могу найти описание, что pIOK имею в виду.

Я пытался посмотреть на это Devel::Peek, perlapi, perlguts, perlxs... В источниках я обнаружил, что:

{SVp_IOK, "pIOK,"}

Но до сих пор не могу найти то, что SVp_IOK является. Что это?

UPD
Я нашел этот документ. Это пролило свет на то, что означают флаги и где они расположены. (остерегайтесь этого DOC немного устарел)

Этот флаг указывает, что объект имеет допустимое непубличное значение поля IVX. Его можно установить только для типа значения SvIV или его подтипов.

UPD

Почему частные и публичные флаги отличаются

1 ответ

Решение

pIOK я показываю Devel::Peek представляет бит, соответствующий битовой маске SVp_IOK, p указывает на "частный" флаг, и он формирует пару с "публичным" флагом IOK (битовая маска SVf_IOK)

Точное значение приватных флагов изменилось в разных версиях Perl, но в общих чертах они означают, что IV (или же NV или же PV) поле SV является "неточным" в некотором роде

Наиболее распространенная ситуация, когда pIOK устанавливается самостоятельно (pIOK всегда устанавливается, если IOK установлен) где PV был преобразован в числовой NV значение. NV а также IV оба поля заполнены, но если IV значение не является точным представлением числа (то есть оно было усечено), то pIOK установлен, но IOK очищается

Этот код показывает способ достижения этого состояния. переменная $pi_str устанавливается в строковое значение для π и преобразуется в значение с плавающей запятой путем добавления 0.0 и сохранения его в $pi_num, Devel::Peek теперь показывает, что NOK/pNOK а также POK/pPOK установлены, но только pIOK в то время как IOK остается ясным. Глядя на 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 так же, как и любое другое значение

Другие вопросы по тегам