【问题标题】:How can I disable constant folding in Perl?如何在 Perl 中禁用常量折叠?
【发布时间】:2021-05-08 07:42:28
【问题描述】:

给定一个类似的命令,

perl -MO=Deparse -E'use constant FOO => 42; print FOO()'

如何禁用常量折叠,这样

print 42;

给我看

print FOO();

之类的。 理想情况下,我希望这是一个适用于所有 Perl 的编译器选项。你可以在 perl 邮件列表[perl #97942] [PATCH] Add -DO option to disable optimizations and disable constant folding and the peephole optimizer when used. 的这个线程中看到这个话题。我试过-DO,但没有用。如果该选项不起作用,我愿意接受变通办法,但它们可能会出现。

【问题讨论】:

    标签: perl compiler-optimization constantfolding


    【解决方案1】:

    常量将自己呈现为 subs。你可以用 sub 做的事情:

    • 将其作为函数调用(FOOFOO()
    • 在覆盖原型时将其作为函数调用 (&FOO())
    • 在继承 @_ (&FOO) 时将其作为函数调用
    • 将其作为方法调用 (__PACKAGE__->FOO)
    • 创建对它的引用(\&FOO*FOO{CODE}。还有 *FOO,其中需要代码引用。)

    只有第一个被折叠。因此,您可以使用

    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say &FOO()' 2>&1 | grep FOO
    5  <#> gv[*FOO] s
    
    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say &FOO' 2>&1 | grep FOO
    5  <#> gv[*FOO] s
    
    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say __PACKAGE__->FOO' 2>&1 | grep FOO
    6  <.> method_named[PV "FOO"] l
    
    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say+ (\&FOO)->()' 2>&1 | grep FOO
    5  <#> gv[*FOO] s
    
    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say *FOO{CODE}->()' 2>&1 | grep FOO
    5  <#> gv[*FOO] s
    
    $ perl -MO=Concise,-exec -E'use constant FOO=>42; say *FOO->()' 2>&1 | grep FOO
    5  <#> gv[*FOO] s
    

    【讨论】:

      【解决方案2】:

      您可以做的一种方法是在常量前面加上&amp;

      perl -MO=Deparse -E'use constant FOO => 42; print &FOO()'
      

      来自perldoc perlsub上的文档

      常量函数 具有“()”原型的函数是内联的潜在候选者。如果优化和常量折叠后的结果是常量或没有其他引用的词法范围标量,那么它将用于代替没有&amp; 的函数调用。使用 &amp; 进行的调用永远不会内联。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-09-05
        • 2016-12-29
        • 2013-11-12
        • 2011-08-16
        相关资源
        最近更新 更多