C++ Logo


Advanced search

Re: Missing changes in P0012R1

From: Jason McKesson <jmckesson_at_[hidden]>
Date: Wed, 17 Mar 2021 10:56:24 -0400
On Wed, Mar 17, 2021 at 4:06 AM v.S. F. via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> Since C++17 (via P0012R1), except specifications have became part of the
> type system, and a noexcept function is implicitly convertible to a pointer
> to a non-noexcept function. However, it seems that calling a noexcept
> function through a pointer to a non-noexcept function is UB, as
> [expr.call]/6 <https://eel.is/c++draft/expr.call#6> remains unchanged
> (known compilers accept such call in constant evaluation in C++17 and later
> modes).
> In the other hand, the definition “int main() noexcept {}” was
> guaranteed to be supported in C++11/14 (as noexcept was not part of the
> function type), but the guarantee is removed by P0012R1, because
> [basic.start.main]/2 <https://eel.is/c++draft/basic.start.main#2> says
> about the type of main and remains unchanged.
> These cases should be addressed as CWG issue(s) IMO.

I don't consider the second case here to be a defect; it's more of a
feature that you're not allowed to declare `main` to be `noexcept`. To
declare a function to be `noexcept` means that it does not emit an
exception to its caller (and if you try, the program will terminate). Well,
`main` has no "caller" as far as the C++ standard is concerned, so who
would it be emitting exceptions to? And if someone tries to emit an
exception from `main`, the program terminates.

Which brings us to the next question: what exactly would `noexcept` `main`

If an appropriate `catch` clause is not found (either before reaching past
`main` or a thread function), `std::terminate` is called. However, whether
the stack is unwound is implementation defined. And this is basically the
same as what happens if you try to throw past a `noexcept` function;
whether the stack is unwound is still implementation-defined.

So what's the point?

Received on 2021-03-17 09:56:37