Subject: Re: Missing non-void return on some paths
From: Jonathan Wakely (cxx_at_[hidden])
Date: 2021-05-08 14:14:23
On Sat, 8 May 2021, 18:56 Scott Schurr via SG12, <sg12_at_[hidden]>
> Hi SG12
> On Thu, May 6, 2021 at 4:47 PM JF Bastien via SG12 <sg12_at_[hidden]>
>> Hello ð UB ð²,
>> (resending.. again... with the right address.... darned email UB)
>> A recent MISRA discussion makes me wonder: *why do we keep this UB
>> Shafik's paper has a short mention here:
>> http://wg21.link/p2234 <http://wg21.link/p2234> also talks about this.
>> The specific wording <http://eel.is/c++draft/stmt.return#2.sentence-8>:
>> Flowing off the end of a constructor, a destructor, or a non-coroutine
>> function with a cv void return type is equivalent to a return with no
>> operand. Otherwise, flowing off the end of a function other than main or a
>> coroutine results in undefined behavior.
>> We have [[noreturn]] to help express programmer intent around this, and
>> we've got a proposal for std::unreachable <http://wg21.link/p0627> (waiting
>> for an update post LWG feedback
>> <https://github.com/cplusplus/papers/issues/275>) which IMO allows
>> expressing intent which [[noreturn]] doesn't express.
>> Compilers diagnose when functions can't be proved to return, and I
>> wouldn't work on a codebase without this diagnostic enabled as an error. Is
>> there a valid reason to keep this UB around? I get that exceptions and
>> longjmp and exit make this diagnostic conservative, but I'd rather have
>> programmers express intent with [[noreturn]] and std::unreachable, which
>> as far as I know compilers diagnose 100% accurately when used to express
>> intent. It seems like we're keeping UB around when we have better tools (
>> [[noreturn]] and std::unreachable) to opt-in to UB.
> I wanted to leave time for someone else to respond. But 24 hours have
> passed and no one else has responded.
> Personally, the only reason I can imagine that the committee has not
> addressed this problem is that no one has written the paper and most folks
> on the committee don't consider it to be a significant problem.
We've never been able to address the objections before. We still can't, but
std:: unreachable should allow us to soon.
> If someone wrote the paper I would certainly support it wholeheartedly.
> This is very much worth doing.
> Three stumbling blocks for such a paper might be:
> 1. Bikeshedding. How should the "I'm explicitly telling the compiler that
> I think my code can't fall off this end" decoration be spelled?
std::unreachable is the proposal in front of us.
> 2. It needs a source backward compatibility story. People need to modify
> their source files to comply with the new rule. What do we tell those
> folks? Do we provide a transition period?
Compilers already warn about it, and provide non-standard equivalents of
[[noreturn]] and std:: unreachable, so a lot of code is likely to be
already complying. Compilers can of course treat their non-standard as
equivalent to the new ones, so code using the existing mechanisms won't
have to switch to the standard ones immediately.
When the standard says something is ill-formed it only takes a diagnostic,
so compilers can issue a warning and still be conforming. So they can
continue to accept it with a warning, or make it an error, and have an
option to choose between the behaviours, and choose if/when to switch the
default to using an error. That's similar to what GCC does for narrowing
conversions, for example. So the standard could say it's ill-formed and
leave it at that. Implementations can manage the transition periods.
> 3. Maybe there's an issue convincing the committee that this is a problem
> worth addressing? Some committee members may consider this to be a "niche
> problem" and solving it provides more pain than benefit
I would be surprised if that's true. We've just never had the tools to do
correctly it. Previously the objections were that we couldn't prove when
flowing off the end was impossible in practice, so we would reject correct
Another possible objection is that in C++ today it's fine to write a
function that flows off the end, as long as you don't call it. If it
becomes ill-formed you can't even write that code. I don't think that's a
good reason to keep the status quo.
Mathias pointed out that currently ignoring a [[noreturn]] attribute should
not change the meaning of a program (because that's a general property of
attributes in C++), but it would not be ok to ignore it if it's presence
affects whether a function is ill-formed or not.
There are also possible issues like
http://lists.isocpp.org/core/2018/02/index.php that might arise.
But I'm in favour of the suggestion, despite the difficulties.
SG12 list run by firstname.lastname@example.org