C++ Logo

std-proposals

Advanced search

Re: [std-proposals] Catch exception thrown from constructor of global object

From: Thiago Macieira <thiago_at_[hidden]>
Date: Thu, 12 Jan 2023 06:32:08 -0800
On Thursday, 12 January 2023 02:23:45 PST Frederick Virchanza Gotham via Std-
Proposals wrote:
> I would almost go so far as to
> propose that C++26 should deprecate defining a global object that
> doesn't satisfy 'is_trivial' so that all such objects would be wrapped
> in an std::optional<T>

std::optional isn't trivial either, so by this rule it would trigger the
deprecation too. It's not even trivially constructible.

It is constexprly constructible, but even then it has a load-time performance
impact because it's not trivially destructible.

> emplaced within the body of 'main', but of
> course I know that I won't get any support on that.

Of course not. You'd break A LOT of code that isn't niche code. Deprecating
bad and niche practices like catch (...) could get some support, and even then
we are finding out not everyone agrees it's bad and niche. Global (namespace-
scope) objects with non-trivial constructors may be a bad practice if you're
interested in load-time performance like I am, but it's NOT niche. It's used
basically everywhere. Deprecating it would cause at least 99% of all C++
software to trigger the deprecation.

> At the very least, maybe we should provide a
> way of ensuring that the terminate handler is set before the
> construction of a global object takes place?

You can do that from... a global (namespace-scope) object's constructor.

And you can avoid SIOF with compiler extensions that set the order in which
such constructor should be run. It's supported by GCC, Clang and MSVC (though
of course the MSVC syntax is different and clunky).

> I do think though that there should be more solid sensibility in the
> Standard surrounding the failure to construct global objects.

I don't think there's anything we need to do here. The problem is not with
C++, it's the code in question. Global objects shouldn't throw on construction
because that terminates the program before it even properly starts. Showing an
exception message to the user is not good UX. Getting to a terminate handler
is not good UX. I'd even argue that this global object shouldn't be trying to
acquire any resources this early, except for memory, but if it is failing to
get the resource it needs, it should exit() the program after a proper error
message to the user explaining what went wrong.

In an application I work with, we once had it react to a "--start-at=x"
command-line parameter (with literal "x") by crashing with SIGABRT after
saying a std::runtime_exception was thrown and not caught. This happened
because a developer used std::stoi on the parameter and failed to handle the
exceptions.

I fixed it by changing to strtoll().

-- 
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
   Software Architect - Intel DCAI Cloud Engineering

Received on 2023-01-12 14:32:11