【问题标题】:Perl : "Use of uninitialized value" though values are initializedPerl:尽管值已初始化,但“使用未初始化的值”
【发布时间】:2015-07-29 21:46:27
【问题描述】:

虽然我在开始时已正确初始化所有变量,但 Perl 正在报告警告。 这是我生成随机单播 mac-address 的代码:

our $OCTATE_MAX = 255; #Max value stored in 8-bit field
our $octate1 = 0;
our $octate2 = 0;
our $octate3 = 0;
our $umac_serial = "";
sub get_umac_serial
{
    # Can not use sprintf as there is an issue with Igloo-JT
    #return "00:" . sprintf ("\00", int(rand(100))) . ":" . sprintf("\00",int(rand(100)));
     my $first = int(rand(99));
     my $second = int(rand(99));

     return "00:" . "$first" . ":" . "$second";
}
sub get_umac_address
{
    $octate1 = $octate1 + 1;
    $octate1 = int(rand(99));
    $octate2 = int(rand(99));
    $octate3 = int(rand(99));
    if ($octate1 >= $OCTATE_MAX)
    {
        $octate2 = $octate2 + 1;
        $octate1 = 0;
    }
    elsif ($octate2 >= $OCTATE_MAX)
    {
        $octate1 = 0;
        $octate2 = 0;
        $octate3 = $octate3 + 1;
    }
    elsif ($octate3 >= $OCTATE_MAX)
    {
        $umac_serial = get_umac_serial();
        print("Unicast mac-serial # $umac_serial\n");
        $octate1 = 0;
        $octate2 = 0;
        $octate3 = 0;
    }
    $umac_serial = get_umac_serial();
    #my $mac_addr = $umac_serial . ":" . sprintf("\00", $octate3) . ":" . sprintf("\00", $octate2) . ":" . sprintf("\00",$octate1);

    my $mac_addr = $umac_serial . ":" . "$octate3" . ":" . "$octate2" . ":" . "$octate1";

    print("MAC ADDR - $mac_addr\n");
    return $mac_addr;
}
return $result;
#exit;
}   ####### End of mac_addr

虽然值已正确初始化,但 perl 会引发以下错误:

Jul 29 01:14:25 [WARN ] perl: Use of uninitialized value in addition (+) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 77. Use of uninitialized value in addition (+) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 77. 
Jul 29 01:14:25 [WARN ] perl: Use of uninitialized value in numeric ge (>=) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 81. Use of uninitialized value in numeric ge (>=) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 81. MAC ADDR - 00:74:53:58:33:0 
Jul 29 01:14:25 [WARN ] perl: Use of uninitialized value in numeric ge (>=) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 81. Use of uninitialized value in numeric ge (>=) at /var/lib/igloo_jt/explorer/2015/7/1251/mac_addr.pm line 81. 
MAC ADDR - 00:51:68:64:69:0

这段代码有什么问题?

【问题讨论】:

  • 显示你的真实代码。您粘贴的内容没有 77 行。
  • 您可能有兴趣知道$octate1++ 不会触发$octate1 = $octate1 + 1 的未定义警告,当变量为undef 时。
  • 另外,为什么在覆盖下一行的值时将其分配给$octate1"00:" . "$first" . ":" . "$second" 很痛苦。应该写成"00:$first:$second",或者更好的是join ":", "00", $first, $second
  • @AnilKumarKK “怎么可能是 undef ?” - 要回答这个问题,您需要完整显示您的真实代码
  • 我发现尾部附加的 return 行的存在相当可疑。

标签: perl shell initialization perl-module


【解决方案1】:

我敢打赌,在程序的顶部,即您未在问题中显示的部分,您的主程序代码正在调用这些子程序中的一个或多个。

当您使用myour 声明变量时,初始化不会在编译时发生。只有在正常的程序流程到达语句时才会发生这种情况。

如果我的预感是正确的,您可以通过将声明移至程序顶部,然后再调用使用变量的函数来解决此问题。或者您可以像这样编写显式编译时初始化:

our $octate1;
our $octate2;
our $octate3;
BEGIN
{
    $octate1 = $octate2 = $octate3 = 0;
}

【讨论】:

  • our $octate1 = 0;这不是将变量初始化为0吗?
  • 初始化,没有。它确实将 0 分配给变量,但仅当程序流到达源文件中的那个点时。就好像您将 our $octate1; 放在文件的顶部,然后将 $octate1=0; 放在文件的后面。
【解决方案2】:

我们无法真正回答您的问题,因为您的代码不是 77 行长。打开strictwarnings 也会有所帮助。

但是我可以建议你做一些比你需要的更复杂的事情 - 如果你试图生成一个随机的十六进制字符串 mac 地址:

print join ( ":", map { sprintf("%02X", int (rand(  256))-1) } (0..5) );

或者如您所指需要00 前缀:

print join ( ":", "00", map { sprintf("%02X", int (rand(  256))-1) } (0..4) );

我不确定您对 sprintf 的问题是什么 - 它是工作的工具 - 但如果这不起作用,还有其他选项可以转换(您可能需要编写自己的 'dectohex' 函数:

sub dec2hex_str {
    my ($value) = @_;
    my @conv = ( 0 .. 9, "A" .. "F" );
    my $result = '';
    while ($value) {
        my $mod = $value % 16;
        $value -= $mod;
        $value /= 16;
        $result = $conv[$mod] . $result;
    }
    if ( length($result) < 2 ) {
        $result = "0" . $result;
    }
    return $result;
}

【讨论】:

    猜你喜欢
    • 2011-03-03
    • 2011-07-19
    • 1970-01-01
    • 2016-09-25
    • 2013-04-08
    • 1970-01-01
    • 2014-02-05
    • 1970-01-01
    • 2021-11-27
    相关资源
    最近更新 更多