C++ Logo

SG12

Advanced search

Subject: Re: Missing non-void return on some paths
From: Arthur O'Dwyer (arthur.j.odwyer_at_[hidden])
Date: 2021-05-08 14:29:07


On Sat, May 8, 2021 at 3:04 PM JF Bastien via SG12 <sg12_at_[hidden]>
wrote:

> On Sat, May 8, 2021 at 11:52 AM Nevin Liber via SG12 <
> sg12_at_[hidden]> wrote:
>
>> On Thu, May 6, 2021 at 6:47 PM JF Bastien via SG12 <sg12_at_[hidden]>
>> wrote:
>>
>>> 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?
>>>
>>
>> How does one write an assert-type macro which, when it is disabled, still
>> prevents this type of warning/error? Because people do write:
>>
>> my_assert(false);
>>
>> to mean abort in debug mode, take my chances in release mode.
>>
>
> I don’t think I understand what you’re asking... but it sounds like
>
> #ifdef _DEBUG
> #define YOLO() abort()
> #else
> #define YOLO() std::unreachable() // or __builtin_unreachable()
>

That looks right to me.

JF,
(1) You originally mentioned "[[noreturn]]" in the same breath with
"unreachable," which is confusing to me. Suppose I write a function `f1`
declared `[[noreturn]]`, which "seemingly falls off the end"; say, `void
g(); [[noreturn]] int f1() { g(); }` — Does f's code clearly indicate my
intent that "I know g() is non-returning, so please don't warn here," or
does f's code suggest to the compiler that I've written a bug?
Would you make it so that a conforming compiler required to diagnose this
code as ill-formed? Or required *not* to diagnose it?

(2) How do we standardize the idea that the compiler should be able to do
control flow analysis here? I mean, if we have, like, `int f2() { while
(true) { if (rand()) return 42; } }`, is a conforming compiler supposed to
be smart enough to see the end of the function is unreachable? Or what if
it's, like,
    int f3(bool b) {
        if (b) { return 42; }
        if (!b) { abort(); } // or std::unreachable(), your choice
    }
Would you make it so that a conforming compiler required to diagnose this
code as ill-formed? Or required *not* to diagnose it?

(3) Alternatively, are you proposing that a conforming compiler should be
forced to insert a call to `std::terminate()` at the bottom of any function
it can't prove isn't reached? (That would be nicely consistent with the big
oops C++ made with `noexcept`.)

Basically, "needs a paper, needs Tony Tables."

my $.02,
–Arthur



SG12 list run by sg12-owner@lists.isocpp.org