A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://github.com/cplusplus/draft/issues/4863 below:

[lib] Extend exception propagation to cover the initialization LWG3640 · Issue #4863 · cplusplus/draft · GitHub

Problem and solution

The wording for the specification of facilities that propagate exceptions inadvertently exclude some cases of thrown exceptions. The ones I've identified have the form "any exception thrown by the {(selected) constructor,construction} of {T,some object}". This formulation excludes exceptions thrown by the initialization of the constructor's parameters ([expr.call] p7). These are not thrown by the constructor nor during the construction of the object (after its construction has begun ([class.cdtor] p1)).

Implying that the initialization of the constructor's parameter are part of the effects for which exceptions are propagated can be done with these changes:

The former is already present in the standard, as exemplified below. As for the latter (emphasis mine),

The process of initialization described in [dcl.init] applies to all initializations regardless of syntactic context, including the initialization of a function parameter ([expr.call]), the initialization of a return value ([stmt.return]), or when an initializer follows a declarator.
-- https://eel.is/c++draft/dcl.init p1

Examples Example, good

Constructors and member functions of pair do not throw exceptions unless one of the element-wise operations specified to be called for that operation throws an exception. -- https://eel.is/c++draft/pairs.pair#1

Talking in terms of operations includes initialization.

Example, bad

For each tuple constructor, an exception is thrown only if the construction of one of the types in Types throws an exception. -- https://eel.is/c++draft/tuple.cnstr#2

We can make a tuple constructor throw an exception other than by constructing one of the specified types: https://godbolt.org/z/enGThMq4P.

#include <tuple>
struct X { X(int) { } };
struct Y { operator int() { throw 0; } };
int main() { std::tuple<X>(Y{}); }

As described at the top, this throws before beginning the construction of an X subobject.

Do note that the constructor above is described to initialize:

Effects: Initializes the elements in the tuple with the corresponding value in std​::​forward(u). -- https://eel.is/c++draft/tuple.cnstr#13

One could argue that [tuple.cnstr] doesn't say "if and only if". That just leaves in the air what happens in this case.

Example, good

Throws: Any exception thrown by the initialization of the selected alternative Tj. -- https://eel.is/c++draft/variant.ctor#18
Throws: Any exception thrown by calling the selected constructor of T. -- https://eel.is/c++draft/variant.ctor#23


RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4