Can elision copying occur in catch statements?

Consider an exception class with a copy constructor with side effects.

Can the compiler skip calling the copy constructor here:

try { throw ugly_exception(); } catch(ugly_exception) // ignoring the exception, so I'm not naming it { } 

How about this:

 try { something_that_throws_ugly_exception(); } catch(ugly_exception) // ignoring the exception, so I'm not naming it { } 

(yes, I know this is very ugly, it was inspired by another question )

+8
c ++ optimization exception copy-elision
source share
3 answers

Yes, this can be eliminated both during throwing and when fishing. For fishing, it can be excluded only when the type specified in the catch clause is the same (except for cv-qualifications) as the type of the exception object. For a more detailed and detailed description, see C ++ 11 12.8 / 31.

... This exclusion of copy / move operations, called copying, is permitted in the following cases (which can be combined to eliminate multiple copies):

...

  • in the throw expression, when the operand is the name of a non-volatile automatic object (except for a function or catch-clause parameter), the scope of which does not go beyond the innermost enclosing try block (if there is one), the copy / move operation from the operand to the exception object (15.1 ) can be omitted by creating an automatic object directly to an exception object

...

  • when an exception handler exception declaration (Article 15) declares an object of the same type (except for cv-qualification) as an exception object (15.1), the copy / move operation can be omitted by treating the -declaration exception as an alias for the exception object if the program value does not change , with the exception of executing constructors and destructors for an object declared as an exception.
+9
source share

I think this is specifically permitted. For C ++ 03, 15.1 / 3 it says:

An expression expression initializes a temporary object called an exception object,

and 12/15 says:

when a temporary class object that is not attached to a link (12.2) is copied to a class object with the same cv-unqualified type, the copy operation can be omitted by constructing the temp object directly to the target of the missed copy

Thus, a secret shelter where exceptions are kept in flight is defined by the standard as temporary and therefore valid for copying.

Edit: oops, now I read further. 15.1 / 5:

If the use of a temporary object can be eliminated without changing the value of the program, with the exception of executing constructors and destructors associated with the use of a temporary object (12.2), then an exception in the handler can be initialized directly with the argument of the throw expression.

It does not become clearer.

Will it really be ... if the catch clause was to raise the exception again (including if it raised invisible code that could do this), then the implementation requires that the "temporary object called the exception object" is still be next to. Thus, some restrictions may arise when this copying is possible. Obviously, an empty catch clause cannot re-raise it.

+4
source share

Yes. If catch gets an exception by reference, then the copy will not (well, by definition).

But I think that this is not your question, and I believe that the code you wrote is specially written without mentioning the link. If so, then yes, even then, copying may be canceled. In fact, initializing a variable in catch is direct initialization in theory. And copying in direct initialization can be undone by the compiler, where possible.

C ++ 03 ยง8.5 / 14 reads,

[...] In some implementation cases, it is allowed to exclude copying inherent in this direct initialization by creating an intermediate result directly in the initialized object;

0
source share

All Articles