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

狂风中的少年 提交于 2021-02-19 01:35:07

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!