2014-02-10 40 views
3

當在Perl的API看,我想知道爲什麼爲什麼sv_setref_pv()在IV槽中存儲它的void *參數?

  • sv_setref_iv()存儲其IV參數在IV插槽,
  • sv_setref_nv()存儲其NV參數在NV插槽,
  • sv_setref_pv()存儲其void *IV插槽的參數,而不是PV插槽?

我有一種預感(CUR的和LEN領域就沒有意義了這樣一個變量),但我想有一個人在XS知識淵博的意見:-)

回答

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個字節。

+0

瑣事:SvIV的IV插槽和SvPV的PV插槽位於相同的偏移處。見[illguts](http://search.cpan.org/dist/illguts/) – ikegami

+0

謝謝您的深刻解答!在我自己的實驗中,我嘗試着和沒有祝福;在前一種情況下,產生了一個PVMG結構,其中包含一個PVX槽,增加了我的困惑。我現在只是重試而沒有祝福,而且在您寫作時確實會分配一個SvIV結構。我沒有想過節省內存,但現在完全合理! – Edward

+0

重新評論:剛剛嘗試過,令我驚訝的是,SvPVX和SvIVX確實返回相同的(存儲)值!鑑於SvIV和SvPV的結構已經通過各種版本的Perl發展,我想我不應該依賴這個,特別是因爲SvPOK不是真的。 – Edward

相關問題