我认为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(如果我取消注释,则会发出一条曲线)。是什么给了什么?
一个有趣的事情是,有其他数据实例为0但没有引发警告。这个其他0数据由不同的函数处理,并且在抛出警告的行之后发生,但处理是相同的(除了上面代码中明显的调试操作,仅由于警告而添加)。
E.G。
sub ppReg_RX_Master_Mode_Reg {
my( $data ) = @_; # first arg should be the Data field
my $ret = "\t";
my( $hex ) = hex($data);
不会发出任何警告。
答案 0 :(得分:1)
这不太可能是Perl的问题。
请记住,警告会发送到STDERR,而您的输出将发送到STDOUT。这两者不一定是同步的,所以你不能将警告与同一记录的输出联系起来。
使用print
和die
代替croak
可能有所帮助,以便以正确的顺序显示警告。
我建议您将子程序更改为
sub ppReg_TX_Mode_Reg {
my ($data) = @_;
do { warn 'Undefined $data parameter'; return; } unless defined $data;
. . .
}
这样就不会对无效数据执行代码。
您的问题可能出在从文件记录中提取数据的代码中。你正确处理空行吗?如果您需要帮助,请显示此部分代码。
答案 1 :(得分:1)
正如预期的那样,问题在于我的代码而不是Perl :) 我正在使用Dispatch Table来调用我的处理函数。 Dispatch Table定义中的拼写错误导致在Perl处理表的声明时调用该函数。
违规代码:
# 'Dispatch table' is a hash for functions
my %regPPFn = (
TX_Version_Reg => \&ppReg_TX_Version_Reg,
TX_Mode_Reg => \&ppReg_TX_Mode_Reg,
TX_Run_Reg => \&ppReg_TX_Run_Reg,
...
# Note: GCs are mostly TXs, so mostly call the TX fn()s
GC_Version_Reg => \&ppReg_TX_Version_Reg,
GC_Mode_Reg => &ppReg_TX_Mode_Reg,
GC_DMA => \&ppReg_GC_DMA,
GC__Reg => \&ppReg_GC__Reg,
"" => sub { print "Dispatch table NULL lookup\n" }
); # Array of pointers to register Pretty Print functions
您可以看到* GC_Mode_Reg *的函数引用缺少&符号前的反斜杠。
GC_Mode_Reg => &ppReg_TX_Mode_Reg,
应该是
GC_Mode_Reg => \&ppReg_TX_Mode_Reg,
使用Data :: Dumper是让我走上正轨的第一步,并向我展示我的功能在“可能被称为”之前被调用了一次。使用$ | = 1也帮助我相信输出文本排序;我原以为在打印报表之前出现的警告信息是由于缓冲。
由于解决方案与最初的假设/问题标题相差甚远,请告诉我是否&你怎么想我应该编辑这个问题。我不愿意改变它,因为有同样问题的其他人可能会像我一样在错误的地方寻找。