C++ Logo

std-discussion

Advanced search

Re: Throwing noncopyable temporaries

From: Jens Maurer <Jens.Maurer_at_[hidden]>
Date: Fri, 2 Sep 2022 08:19:35 +0200
On 01/09/2022 13.55, Schneider, Robert via Std-Discussion wrote:
> Hi,
>
> GCC and clang at the moment allow throwing of noncopyable prvalue expressions:
>
> struct foo
> {
> foo() = default;
> foo(foo const&) = delete;
> foo(foo&&) = delete;
> };
>
> void bar()
> {
> throw foo();
> }
> https://compiler-explorer.com/z/d7h8f8ror
>
> I was wondering if that's intended, since I can't quite relate it to the wording of except.throw#5:
>
>> When the thrown object is a class object, the constructor selected for the copy-initialization as well as the constructor selected for a copy-initialization considering the thrown object as an lvalue shall be non-deleted and accessible, even if the copy/move operation is elided ([class.copy.elision]).
>
> As far as I understand, mandatory copy elision means that the constructor selected for copy-initialization in this case is the _default constructor_. Copy-initialization doesn't even consider copy/move constructors here. The part about "the thrown object as an lvalue" doesn't make sense to me in this context.

When we throw an exception, we want to make sure it can be caught:

void bar()
{
  try {
    throw foo();
  } catch (foo x) { // invokes copy constructor using an lvalue "foo"

  }
}

This situation could also be handled by making the handler ill-formed.

The interesting aspect is that gcc differs in its behavior depending on
whether S has data members or not:


struct S
{
  S() = default;
  S(const S&) = delete;
  // int x = 0; // #1
};

int main()
{
  try {
    throw S();
  } catch (S s) {
    return 1;
  }
}


but if "int x" is present, I get:


x.cc:13:14: error: use of deleted function ‘S::S(const S&)’
   13 | } catch (S s) {
      | ^
x.cc:5:3: note: declared here
    5 | S(const S&) = delete;
      | ^


That feels seriously inconsistent.


> Anyway, was this change intended? Should the example above compile?

The example you gave should not compile, per the current wording.

Jens

Received on 2022-09-02 06:19:40