On Sat, 8 May 2021, 18:56 Scott Schurr via SG12, <sg12@lists.isocpp.org> wrote:
Hi SG12

On Thu, May 6, 2021 at 4:47 PM JF Bastien via SG12 <sg12@lists.isocpp.org> wrote:
(resending.. again... with the right address.... darned email UB)

A recent MISRA discussion makes me wonder: why do we keep this UB around?

Shafik's paper has a short mention here: http://wg21.link/P1705#stmtreturn
 http://wg21.link/p2234 also talks about this.

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 (waiting for an update post LWG feedback) 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 code.

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.