Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Who manages the exception thrown by a copy constructor in parameters? [duplicate]

Assume I have this function

void foo() noexcept
{
   // Safely noexcept code.
}

And then this class:

class Bar
{
   Bar(const Bar&) { ... } // Is not noexcept, so might throw
   // Non movable:
   Bar(Bar&&) = delete;
};

Now, I need to modify foo() to receive a Bar by value:

void foo(Bar bar) // noexcept?
{
   // Safely noexcept code
}

I assume the copy of Bar is done before the call to foo, so the code of foo could theoretically still be noexcept, but I am not sure how is that at C++ level defined. Does foo need to get the noexcept deleted or is the caller who might throw when coping Bar? Does it depend on the call mode(stdcall, farcall, etc..) or compiler? Update: In other questions I did not found any reference to the call convention. That should make a difference on the behavior. I supose.

like image 802
LeDYoM Avatar asked Oct 15 '22 11:10

LeDYoM


1 Answers

See [expr.call]/4:

The initialization and destruction of each parameter occurs within the context of the calling function. [ Example: The access of the constructor, conversion functions or destructor is checked at the point of call in the calling function. If a constructor or destructor for a function parameter throws an exception, the search for a handler starts in the scope of the calling function; in particular, if the function called has a function-try-block (Clause 18) with a handler that could handle the exception, this handler is not considered. —end example ]

Therefore you can still mark foo noexcept, even though the initialization of bar might throw. The calling function should not be noexcept. (That is, unless you're ok with the program being terminated in case of an exception.)

like image 134
Brian Bi Avatar answered Oct 21 '22 04:10

Brian Bi