C++ Logo

sg12

Advanced search

Re: [SG12] Missing non-void return on some paths

From: JF Bastien <cxx_at_[hidden]>
Date: Sat, 8 May 2021 13:52:02 -0700
On Sat, May 8, 2021 at 1:45 PM Arthur O'Dwyer via SG12 <
sg12_at_[hidden]> wrote:

> On Sat, May 8, 2021 at 4:14 PM Nevin Liber via SG12 <sg12_at_[hidden]>
> wrote:
>
>>
>> What about assert(b) when NDEBUG is not defined? JF said that would
>> become an unconditional call to std::unreachable, but calling
>> std::unreachable invokes UB. From the paper: "The author feels that the
>> best way is to make the behavior of std::unreachable() be undefined."
>>
>
> I believe JF was responding to your `assert(false)` situation. The
> standard `assert` actually already does the right thing; it's basically
>
> #define assert(x) (x ? void() : std::abort())
>
> where `std::abort()` is (at least hypothetically) annotated with
> [[noreturn]].
>
> constexpr int f4(int x) { assert(x > 0); if (x == 42) return 42; }
>
> Here, in C++14-and-later, the compiler can trace individual "attempted
> constant-evaluation runs" and *observe* that
> - `f4(-1)` evaluates non-constexpr function std::abort() and therefore is
> not a constant expression
> - `f4(42)` evaluates to 42
> - `f4(1)` falls off the end of the function and therefore is not a
> constant expression
>
> In JF's hypothetical future, AIUI, the compiler would also be able to do
> control-flow (and data-flow?) analysis and *prove symbolically* that
> - `f4(x)` for (x <= 0) evaluates [[noreturn]] function std::abort() and
> therefore is OK
> - `f4(x)` for (x == 42) returns a value along all codepaths and therefore
> is OK
> - `f4(x)` for (0 < x && x != 42) falls off the end of the function and
> therefore is *not OK*
> and, since there exists at least one "*not OK*" case, therefore the
> definition of `f4` is ill-formed (even if `f4` is never *actually*
> evaluated on any of the problematic inputs).
>

I don’t think that’s something I’d propose. It seems better to mandate that
all paths clearly return, or be annotated with no return, unreachable,
throw, or (list of similar terminators).

Specifying data flow analysis seems like something we wouldn’t want to
standardize.

So the error would be not as smart as could be, but it would just forbid
overly clever code.

Hence why I ask if it’s been discussed and what prior preferences might
have been.

>

Received on 2021-05-08 15:52:15