【发布时间】:2012-06-04 19:15:13
【问题描述】:
我认为 PERL(CentOS 内核 2.6.18-308.8.1.el5 上的 5.8.8)给了我一个误报的“未初始化变量”警告。我所有的搜索都出现了合法的未初始化值问题。也许我的也是,如果是这样的话,那么对正在发生的事情(以及如何正确地做我想做的事情)的解释会很棒。我还查看了许多关于 hex() 和正确的函数参数习语的参考资料,我认为我做的都是正确的。
我的脚本读取 2 个文本文件:一个包含 32 位硬件地址,另一个包含从该地址读回的 32 位数据。每个文件中的值总是 8 个十六进制数字长,并且两个文件都是 100% 匹配的(地址文件中的第 1 行对应于数据文件中的第 1 行)。当数据值为非零时,一切都很好,但当数据值为 0 时,我收到警告:
Use of uninitialized value in string eq at ../VMetro_Parser.pl line 248.
Use of uninitialized value in hex at ../VMetro_Parser.pl line 250.
相关代码:
sub ppReg_TX_Mode_Reg {
my( $data ) = @_; # first arg should be the Data field
my $ret = "\t";
if( $data eq "00000000" ) { print "TX_Mode_Reg got 0 input\n"; } #LINE 248
#croak( "data not defined!" ) unless defined $data;
my( $hex ) = hex($data); #LINE 250
$ret .= sprintf( "Clear INTs: %02X ", (($hex >> 25) & 0x7F) );
产生预期行为的输入:
Address: 90000004
Data: 00000004
PERL 脚本的输出:
90000004 00000004 -> Wr TX00 Mode_Reg
Clear INTs: 00
产生意外“未初始化值”警告的输入:
Address: 90000004
Data: 00000000
PERL 脚本的输出:
90000004 00000000 -> Wr TX00 Mode_Reg
TX_Mode_Reg got 0 input
Clear INTs: 00
很明显,它正在识别作为字符串“00000000”传入的参数,但它也认为它是 undef(如果我取消注释,就会触发 croak 行)。什么给了?
一个有趣的事情是,还有其他数据为 0 的实例,但没有引发任何警告。其他 0 数据由不同的函数处理,发生在引发警告的行之后,但处理相同(除了上面代码中明显的调试操作,只是因为警告而添加)。
例如
sub ppReg_RX_Master_Mode_Reg {
my( $data ) = @_; # first arg should be the Data field
my $ret = "\t";
my( $hex ) = hex($data);
不抛出任何警告。
【问题讨论】:
-
您声称的输出中没有任何警告?!?!
-
语言名称是“Perl”。这不是首字母缩写词。
-
use Devel::Peek qw( Dump ); Dump($data);(在比较之前)可能具有指导意义。 -
您应该使用
Data::Dumper检查您的输入。这是调试脚本的一种很好的方式,也是一个核心模块。print Dumper $data会让你确切地知道你的变量中有什么。此外,您的问题中没有足够的信息来做任何事情,只能猜测,所以我建议您尽可能设置一个独立的示例。 -
@TLP,Data::Dumper 不会让您知道“变量中的确切内容”。这就是我建议的 Devel::Peek。如果这是 Perl 中的错误,那么额外的细节会很重要。