C++ Logo

std-discussion

Advanced search

Re: Is the standard clear enough about throwing exceptions from functions that return prvalues?

From: Andrew Schepler <aschepler_at_[hidden]>
Date: Fri, 20 Sep 2019 13:19:28 -0400
By my reading, foo should catch the exception, so gcc and clang are
correct. The key quote is [stmt.return]/2
<https://timsong-cpp.github.io/cppwp/stmt.return#2>: When the returned
initializer is not an expression with type void,

the return statement initializes the glvalue result or prvalue result
object of the (explicit or implicit) function call by copy-initialization
from the operand.


So even though the prvalue result object is s in main, the initialization
and the exception throwing happen in foo.

I suppose this means we should think of prvalue temporary materialization
as only a piece of semantic analysis of a class type expression in its
context, and not something that gets "executed" by the virtual machine.

-- Andrew Schepler



On Fri, Sep 20, 2019 at 12:36 PM Brian Bi via Std-Discussion <
std-discussion_at_[hidden]> wrote:

> In the following program, no prvalue materialization conversion should
> occur. Instead, s should just be value-initialized:
>
> #include <iostream>
>
> struct S {
> S() { throw 42; }
> S(S&&) { std::cout << "I am nontrivial" << std::endl; }
> };
>
> S foo() {
> try {
> return {};
> } catch (int) {
> std::cout << "caught by foo\n";
> throw;
> }
> }
>
> int main() {
> try {
> S s = foo();
> } catch (int) {
> std::cout << "caught by main\n";
> }
> }
>
> Therefore, I would expect that the constructor of S should be called in
> the context of the definition of s, and foo should not have the
> opportunity to catch the exception. Put another way, conceptually, the last
> thing foo() does before it returns is to create a prvalue that says to
> value-initialize the S object (whenever that might finally be required);
> it doesn't get to actually call the constructor.
>
> Yet GCC and Clang both give foo the opportunity to catch the exception,
> as if the constructor call were being done in the context of foo.
> http://coliru.stacked-crooked.com/a/ae2943b361ab51a9
>
> Is the standard clear enough that the behaviour of GCC and Clang in this
> case is actually the intended behaviour? I think that it is not clear.
>
> --
> *Brian Bi*
> --
> Std-Discussion mailing list
> Std-Discussion_at_[hidden]
> https://lists.isocpp.org/mailman/listinfo.cgi/std-discussion
>

Received on 2019-09-20 12:21:49