Mailing List Archive

code after exit
A quote from perldiag:
Statement unlikely to be reached
(W exec) You did an exec() with some statement after it other than a
die(). This is almost always an error, because exec() never returns
unless there was a failure. You probably wanted to use system()
instead, which does return. To suppress this warning, put the exec()
in a block by itself.

In practice:
$ perl -Mwarnings -C -E 'exec "true"; say "Hello."'
Statement unlikely to be reached at -e line 1.
(Maybe you meant system() when you said exec()?)

Is there some reason, other than "not implemented yet", that we don't have a similar warning for "exit"?

(This came up because a coworker wrote "exit $OK ? 0 : 1", which I know that even this wouldn't catch.)

--
rjbs
Re: code after exit [ In reply to ]
On 11/18/23 18:20, Ricardo Signes wrote:
> A quote from perldiag:
>
> Statement unlikely to be reached
> (W exec) You did an exec() with some statement after it other than a
> die(). This is almost always an error, because exec() never returns
> unless there was a failure. You probably wanted to use system()
> instead, which does return. To suppress this warning, put the exec()
> in a block by itself.
>
>
> In practice:
>
> $ perl -Mwarnings -C -E 'exec "true"; say "Hello."'
> Statement unlikely to be reached at -e line 1.
> (Maybe you meant system() when you said exec()?)
>
>
> Is there some reason, other than "not implemented yet", that we don't
> have a similar warning for "exit"?
>
> (This came up because a coworker wrote "exit $OK ? 0 : 1", which I know
> that even this wouldn't catch.)
>

Let me be clear on what you're asking. Are you saying that if I invoke:

#####
$ perl -Mwarnings -E 'exit 0; say "Hello."'
#####

... you would expect to see a warning starting like this:

#####
Statement unlikely to be reached at -e line 1.
#####

... indicating that 'say "Hello."' is unreachable?


Thank you very much.
Jim Keenan
Re: code after exit [ In reply to ]
On Sat, Nov 18, 2023, at 19:30, James E Keenan wrote:
> Let me be clear on what you're asking. Are you saying that if I invoke:
>
> #####
> $ perl -Mwarnings -E 'exit 0; say "Hello."'
> #####
>
> ... you would expect to see a warning starting like this:
>
> #####
> Statement unlikely to be reached at -e line 1.
> #####

Correct.

--
rjbs
Re: code after exit [ In reply to ]
Ricardo Signes wrote:
>
> A quote from perldiag:
> Statement unlikely to be reached
> [...]
> (Maybe you meant system() when you said exec()?)
>
> Is there some reason, other than "not implemented yet", that we don't have a similar warning for "exit"?

What's special about "exec" is that it isn't clear from its name that it won't return. I think "exit" doesn't have that problem.

If a warning is added for statements after "exit", then we should also have warnings for statements after "die" and "return" at least. Also after stuff like "carp", a subroutine that calls "die".


> (This came up because a coworker wrote "exit $OK ? 0 : 1", which I know that even this wouldn't catch.)

There's no statement after the "exit", so I don't see a problem there. The condition only controls the exit status. Am I missing something?


--
Arne Johannessen
<https://arne.johannessen.de/>
Re: code after exit [ In reply to ]
Ricardo Signes writes:

> Is there some reason, other than "not implemented yet", that we don't
> have a similar warning for "exit"?

When developing or debugging, I often put an early (unconditional) exit
in my code, so I can check how things are running up to a particular
point. I appreciate there are other ways of doing this (for instance
__END__, using an actual debugger, commenting code out), but sometimes
exit is the most convenient. So this would be a behaviour change.

However, given this is running manually when debugging an additional
warning would not be terrible. Even if deemed unnecessary or unwanted,
it would clearly go away once the program is run for real.

And it would at least catch the case where I fix the bug but
inadvertently leave the early exit in there, then am surprised why it
still isn't working!

> (This came up because a coworker wrote "exit $OK ? 0 : 1", which I
> know that even this wouldn't catch.)

That definitely would benefit from a warning, but possibly this case is
more specific than code after exit — attempt to use exit's return value
in an expression, or something like that?

Arne Johannessen writes:

> There's no statement after the "exit", so I don't see a problem there.
> The condition only controls the exit status. Am I missing something?

It is interpreted as this, which obviously nobody intends:

(exit $OK) ? 0 : 1

But I agree that feels like an entirely different sort of programming
mistake than "exit; something_else()" (even if we accept the latter is a
mistake).

The fact that the issue wasn't clear even when told the proposed warning
suggests that somebody who writes the above might not be sufficiently
assisted by a ‘code after exit’ warning, because it still doesn't *look*
like there's any code after the exit statement.

Smylers
Re: code after exit [ In reply to ]
On 19.11.23 08:33, Smylers via perl5-porters wrote:
>
> It is interpreted as this, which obviously nobody intends:
>
> (exit $OK) ? 0 : 1
>
> But I agree that feels like an entirely different sort of programming
> mistake than "exit; something_else()" (even if we accept the latter is a
> mistake).
>

I would expect this to fall under "Possible precedence issue with
control flow operator", like what you get for 'exit $a or 1'.
(Also, if the constants had been anything but 0 and 1, you would've got
a "Useless use of constant in void context" warning.)
Re: code after exit [ In reply to ]
Lukas Mai writes:

> On 19.11.23 08:33, Smylers via perl5-porters wrote:
>
> > It is interpreted as this, which obviously nobody intends:
> >
> > (exit $OK) ? 0 : 1
> >
> > But I agree that feels like an entirely different sort of
> > programming mistake than "exit; something_else()" (even if we accept
> > the latter is a mistake).
>
> I would expect this to fall under "Possible precedence issue with
> control flow operator", like what you get for 'exit $a or 1'.

Yes, though somebody who's made this mistake might still struggle to see
where the control-flow operator is — ?: doesn't feel as much as a
control-flow operator as low-precedence or does.

> (Also, if the constants had been anything but 0 and 1, you would've got
> a "Useless use of constant in void context" warning.)

Which would be fine if those aren't precisely the constants that
somebody making this mistake is most likely to use.

Smylers
Re: code after exit [ In reply to ]
On Sun, Nov 19, 2023 at 1:03?PM Smylers via perl5-porters <
perl5-porters@perl.org> wrote:

> Ricardo Signes writes:
>
> > Is there some reason, other than "not implemented yet", that we don't
> > have a similar warning for "exit"?
>
> When developing or debugging, I often put an early (unconditional) exit
> in my code, so I can check how things are running up to a particular
> point. I appreciate there are other ways of doing this (for instance
> __END__, using an actual debugger, commenting code out), but sometimes
> exit is the most convenient. So this would be a behaviour change.
>

The thing about good warnings is that they should generally have a very low
false positive rate, and I think this warning would have too many false
positives for exactly the reason you just described.

Some things are better off left for linters, which are allowed to have a
much higher false positive rate.

Leon
Re: code after exit [ In reply to ]
On 19.11.23 09:08, Smylers via perl5-porters wrote:
> Lukas Mai writes:
>
>> On 19.11.23 08:33, Smylers via perl5-porters wrote:
>>
>>> It is interpreted as this, which obviously nobody intends:
>>>
>>> (exit $OK) ? 0 : 1
>>>
>>> But I agree that feels like an entirely different sort of
>>> programming mistake than "exit; something_else()" (even if we accept
>>> the latter is a mistake).
>>
>> I would expect this to fall under "Possible precedence issue with
>> control flow operator", like what you get for 'exit $a or 1'.
>
> Yes, though somebody who's made this mistake might still struggle to see
> where the control-flow operator is — ?: doesn't feel as much as a
> control-flow operator as low-precedence or does.

The control flow operator in question is exit (not ?:). It redirects the
control flow so that it never returns to ?:.

>> (Also, if the constants had been anything but 0 and 1, you would've got
>> a "Useless use of constant in void context" warning.)
>
> Which would be fine if those aren't precisely the constants that
> somebody making this mistake is most likely to use.

Agreed.