2014-02-10 3 views
3

При взгляде на API Perl, мне было интересно, почемуПочему sv_setref_pv() сохраняет свой аргумент void * в слоте IV?

  • sv_setref_iv() хранит его IV аргумент в слоте IV,
  • sv_setref_nv() хранит его NV аргумент в слоте NV,
  • но sv_setref_pv() хранит его void * аргумент в слоте IV, вместо слота PV?

У меня есть догадка (поля CUR и LEN не имеет смысла для такой переменной), но я хотел бы иметь мнение кого-то знающего в XS :-)

ответ

6

Есть много разных типов скаляров.

  • SvNULL не может содержать никаких значений, кроме undef.
  • SvIV способен удерживать IV, УФ или RV.
  • SvNV способен удерживать NV.
  • SvPV способен удерживать PV.
  • SvPVIV способен удерживать PV, а также IV, UV или RV.
  • ...

А.В., HV, CV, GV действительно только типы скаляр тоже.

Note Я сказал, что «способен» удерживать. Вы можете рассматривать скаляры как объекты, а выше - классы и подклассы. Каждая из вышеперечисленных функций имеет другую структуру.

Наличие этих различных типов скаляров позволяет сохранять память.

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 байт на ссылку.

+0

Общая информация: Слот IV SvIV и слот PV SvPV расположены с одинаковым смещением. См. [Illguts] (http://search.cpan.org/dist/illguts/) – ikegami

+0

Спасибо за ваш проницательный ответ! В моих собственных экспериментах я пытался и без благословения; в первом случае создается PVMG-структура, которая содержит слот PVX, что добавляет меня к путанице. Я сейчас просто не без благословения, и структура SvIV выделяется при написании. Я не думал о экономии памяти, но теперь это имеет смысл! – Edward

+0

Ваш комментарий: просто попробовал, и, к моему удивлению, SvPVX и SvIVX действительно возвращают то же (сохраненное) значение! Видя, что структура SvIV и SvPV развивается через различные версии Perl, я полагаю, что я не должен полагаться на это, тем более что SvPOK не соответствует действительности. – Edward

Смежные вопросы