Unit testing 是否需要告诉Perl编译器不要优化带有忽略返回值的函数调用?

Unit testing 是否需要告诉Perl编译器不要优化带有忽略返回值的函数调用?,unit-testing,perl,optimization,language-specifications,code-elimination,Unit Testing,Perl,Optimization,Language Specifications,Code Elimination,我正在编写新的Perl5模块,以便在您触摸对象属性时通过设置或获取默认值来检查类型约束。我正在编写单元测试,并希望为后一种情况运行访问器。然而,我担心Perl可能会优化掉我的访问器函数调用,因为返回值被丢弃。会吗?如果是,我能告诉它不要吗?是否记录了相应的行为?如果答案像“别担心”这样简单,那就足够了,但请参考文档:) 当我在Perl 5.26.2 x64 Cygwin上运行以下MCVE时,它成功了。然而,我不知道这是否是有保证的,或者它是否只是碰巧现在起作用,有一天可能会改变 use 5.00

我正在编写新的Perl5模块,以便在您触摸对象属性时通过设置或获取默认值来检查类型约束。我正在编写单元测试,并希望为后一种情况运行访问器。然而,我担心Perl可能会优化掉我的访问器函数调用,因为返回值被丢弃。会吗?如果是,我能告诉它不要吗?是否记录了相应的行为?如果答案像“别担心”这样简单,那就足够了,但请参考文档:)

当我在Perl 5.26.2 x64 Cygwin上运行以下MCVE时,它成功了。然而,我不知道这是否是有保证的,或者它是否只是碰巧现在起作用,有一天可能会改变

use 5.006; use strict; use warnings; use Test::More; use Test::Exception;

dies_ok {   # One I know works
    my $obj = Klass->new;   # Default value of "attribute" is invalid
    diag $obj->accessor;    # Dies, because the default is invalid
} 'Bad default dies';

dies_ok {
    my $obj = Klass->new;
    $obj->accessor;         # <<< THE QUESTION --- Will this always run?
} 'Dies even without diag';

done_testing();

{   package Klass;
    sub new { my $class = shift; bless {@_}, $class }
    sub check { shift; die 'oops' if @_ and $_[0] eq 'bad' }
    sub default { 'bad' }
    sub accessor {
        my $self = shift;
        if(@_) { $self->check($_[0]); return $self->{attribute} = $_[0] }   # W
        elsif(exists $self->{attribute}) { return $self->{attribute} }      # R
        else {  
            # Request to read the attribute, but no value is assigned yet.
            # Use the default.
            $self->check($self->default);    # <<<---- What I want to exercise
            return $self->{attribute} = $self->default;
        }
    } #accessor()
} #Klass
使用5.006;严格使用;使用警告;使用测试::更多;使用Test::异常;
死得好{我知道有一个管用
my$obj=Klass->new;#“attribute”的默认值无效
diag$obj->accessor;#死亡,因为默认值无效
}“严重违约死亡”;
你还好吗{
my$obj=Klass->new;
$obj->accessor;#{attribute}=$[0]}#W
elsif(exists$self->{attribute}){return$self->{attribute}}#R
否则{
#请求读取属性,但尚未分配任何值。
#使用默认值。

$self->check($self->default);#accessor;
以获得类似效果;编译合法地失败,因为
不能修改&Klass::accessor的非左值子例程调用

Perl永远不会优化掉子调用,任何语言都不应该优化掉具有副作用的子调用


undef$obj->accessor
的意思类似于
undef$obj->accessor=undef

对于你的答案,最好有比“AFAIK”更有力的参考/理由。有数百万行Perl代码带有不使用返回值的函数调用。我很乐意支持Ujin734的观点,即Perl永远不会优化它们。如果任何可能产生副作用的东西都被优化掉,那将是一个bug。哈?
perlperf
是关于改进用户代码的提示和技巧。它没有任何问题比如说perl编译器进行的任何内部优化。关于“结果将被丢弃”,在perl中,这只是void上下文,任何函数都可以通过这种方式调用。您的示例不一定应用void上下文,因为它将在任何上下文死亡的情况下被调用\u ok调用周围的函数(最后计算的语句是函数的隐式返回值),但您可以在后面放置一个伪返回值,以便该语句始终处于无效上下文中:
$obj->accessor;1;