C++ Logo

std-proposals

Advanced search

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

From: Edward Catmur <ecatmur_at_[hidden]>
Date: Thu, 12 Jan 2023 18:40:29 +0000
On Thu, 12 Jan 2023 at 18:16, Jason McKesson via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> ---------- Forwarded message ---------
> From: Jason McKesson <jmckesson_at_[hidden]>
> Date: Thu, Jan 12, 2023 at 1:16 PM
> Subject: Re: [std-proposals] Fwd: Catch exception thrown from
> constructor of global object
> To: Edward Catmur <ecatmur_at_[hidden]>
>
>
> On Thu, Jan 12, 2023 at 12:08 PM Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >
> > On Thu, 12 Jan 2023 at 16:52, Jason McKesson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >>
> >> ---------- Forwarded message ---------
> >> From: Jason McKesson <jmckesson_at_[hidden]>
> >> Date: Thu, Jan 12, 2023 at 11:51 AM
> >> Subject: Re: [std-proposals] Catch exception thrown from constructor
> >> of global object
> >> To: Edward Catmur <ecatmur_at_[hidden]>
> >>
> >>
> >> On Thu, Jan 12, 2023 at 11:40 AM Edward Catmur <ecatmur_at_[hidden]>
> wrote:
> >> >
> >> > On Thu, 12 Jan 2023 at 16:17, Jason McKesson via Std-Proposals <
> std-proposals_at_[hidden]> wrote:
> >> >>
> >> >> On Thu, Jan 12, 2023 at 10:34 AM Federico Kircheis via Std-Proposals
> >> >> <std-proposals_at_[hidden]> wrote:
> >> >> > On 2023-01-12 at 11:23, Frederick Virchanza Gotham via
> Std-Proposals
> >> >> > wrote:
> >> >> >
> >> >> > >
> >> >> > >Now if you were to ask me . . . . 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> and emplaced within the body of 'main',
> but of
> >> >> > >course I know that I won't get any support on that.
> >> >> >
> >> >> >
> >> >> > It would also not cover most use-cases, for example
> >> >> >
> >> >> >
> >> >> > ----
> >> >> > /* const */ int i = function_that_throws();
> >> >> >
> >> >> > int main(){
> >> >> > }
> >> >> > ----
> >> >> >
> >> >> >
> >> >> > Also std::optional as global variable is problematic if inside a
> >> >> > library, depending on the visibility of the symbols, the destructor
> >> >> > might be executed more than once (and thus be UB)
> >> >>
> >> >> It seems to me that, to the extent that this is a significant
> problem,
> >> >> static analysis is likely the most effective solution. Static
> analysis
> >> >> tools should be able to detect if the initializer for a global is
> >> >> `noexcept` and there can be options to have such tools give a warning
> >> >> if it isn't. Better tools might be able to follow inlined functions
> to
> >> >> see if anything could actually throw given the value of parameters.
> >> >
> >> >
> >> > As Lénárd says above, this already exists: `constinit`.
> >>
> >> `constinit` means that the initializer must be a constant expression.
> >> But it's not hard to write an initializer that isn't a constant
> >> expression yet does not throw exceptions. Constant expressions cannot
> >> throw exceptions (yet), but there are many expressions that also don't
> >> throw exceptions.
> >
> >
> > Sure, but maybe those should be constant expressions. Other than
> allocation, what is there to do in a constructor that can't already be
> evaluated in constant expressions?
>
> As I mentioned later, you cannot open files (and no, failure to open a
> file is not necessarily a failure to construct an object whose
> constructor opens the file as part of its work. There may be some
> fallback default behavior). Even if such APIs were able to be constant
> expressions, the file may not exist at compile time. Or you may be
> compiling for a completely different system.
>

That seems a lot to be doing before entering `main`, but I accept the point.

Basically, any OS system calls cannot be constant expressions.
>

Yes, and there are some that can't fail, or calls like
`std::chrono::system_clock::now()` (which is `noexcept`). Also apparently
calling `getenv` is valid before entering `main`, and you may well want to
use that to inform static initialization:
https://stackoverflow.com/questions/437279/is-it-safe-to-use-getenv-in-static-initializers-that-is-before-main

Received on 2023-01-12 18:40:42