问题
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.
回答1:
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.)
回答2:
The construction of the parameters happens in the caller; once all parameters have been built/converted the function is called.
Something that may not be obvious is that in C++ even default value expression for non-passed parameters happens in the caller: i.e.
void foo(MyClass x=MyClass()) {
...
}
the construction in case of
foo();
is still done at the caller site, before the function is actually called.
来源:https://stackoverflow.com/questions/58031634/who-manages-the-exception-thrown-by-a-copy-constructor-in-parameters