C++ Logo

STD-DISCUSSION

Advanced search

Subject: Is the standard clear enough about throwing exceptions from functions that return prvalues?
From: Brian Bi (bbi5291_at_[hidden])
Date: 2019-09-20 11:36:27


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 list run by herb.sutter at gmail.com

Older Archives on Google Groups