Perl / perl5

🐪 The Perl programming language
https://dev.perl.org/perl5/
Other
1.98k stars 560 forks source link

[feature]Use of uninitialized value in concatenation (.) or string message could surely mention a little more #17720

Closed jidanni closed 4 years ago

jidanni commented 4 years ago
use strict;
use warnings FATAL => q(all);
sub f { }
sub g { 1; }
my $k = f() . g();

gives Use of uninitialized value in concatenation (.) or string at line ...

Would it "be anymore skin off its back" to please mention if it was f or g? It does if one uses a undefined $f instead of f(); Certainly it could at least mention "the first one" or "the second one" or "the first one and possibly others".

iabyn commented 4 years ago

On Wed, Apr 15, 2020 at 07:39:21AM -0700, 積丹尼 Dan Jacobson wrote:

use strict;
use warnings FATAL => q(all);
sub f { }
sub g { 1; }
my $k = f() . g();

gives Use of uninitialized value in concatenation (.) or string at k.pl line 14.

Would it "be anymore skin off its back" to please mention if it was f or g? It does if one uses $f=undef instead. Certainly it could at least mention "the first one" or "the second one".

That's not realistically possible. The warning is only triggered after both functions have been called, their return values pushed on the stack, then the add op called, which pops the two values off the stack, then (in the general case) calls various C-level functions to get string values from those scalar values. It is usually one of those functions which finally notices that the value is undef and outputs a warning.

The warning function has no way of knowing at that point where the value came from.

Perl sometimes identifies the undef variable in things like $.$y, buts that's only because the 'undef warning' function knows what op is currently being executed (an OP_CONCAT say) and can examine the optree directly under that op looking for simple cases like OP_PADSV. If it finds such ops, it can sometimes determine retrospectively what SV that op would have pushed onto the stack, and if that SV has the same address as the SV currently being complained about, it can produce a more detailed warning message.

-- O Unicef Clearasil! Gibberish and Drivel! -- "Bored of the Rings"

jidanni commented 4 years ago

Fine. From now on I'll stick to one operation per line.

$k .= f();
$k .= g();

At least perl will tell me the line number where the problem occurred.