In [except.ctor] lo standard (N4140) garantisce che:I valori di ritorno delle funzioni sono oggetti automatici e quindi sono garantiti per essere distrutti?
... distruttori vengono invocati per tutti gli oggetti automatici costruiti dal momento che il blocco try è stato immesso ...
Tuttavia, nell'esempio seguente, lo output vuoto dimostra che il valore restituito della funzione foo
non è stato destrutturato, sebbene sia stato costruito. Compilato usando g ++ (5.2.1) e clang ++ (3.6.2-1) e con le opzioni -O0 -fno-elide-constructors -std=c++14
.
struct A { ~A() { cout << "~A\n"; } };
struct B { ~B() noexcept(false) { throw 0; } };
A foo() {
B b;
return {};
}
int main() {
try { foo(); }
catch (...) { }
}
È questo un bug sia in g ++ e clang ++, o sono i valori di ritorno delle funzioni non considerati oggetti automatici, o è una scappatoia nel linguaggio C++?
In nessuno dei [stmt.return], [expr.call] o [dcl.fct] Sono stato in grado di trovare una dichiarazione chiara se un valore di ritorno della funzione è considerato un oggetto automatica . I suggerimenti che ho trovato più vicini sono 6.3.3 p2:
... Una dichiarazione di ritorno può prevede la costruzione e copiare o spostare di un oggetto temporaneo ...
e 5.2.2 p10 :
una chiamata di funzione è un lvalue se il tipo risultato è un tipo di riferimento lvalue o un riferimento rvalue operato tipo, un xValue se il tipo di risultato è un riferimento rvalue al tipo di oggetto, ed una prvalue altrimenti .
Ho scoperto che sia gcc che clang hanno già registrato questo errore da anni, quindi non mi aspetto che lo risolvano presto: [gcc] (https://gcc.gnu.org/bugzilla/show_bug.cgi ? id = 33799), [clang] (https://llvm.org/bugs/show_bug.cgi?id=12286). –
Il compilatore è autorizzato ad omettere la stessa costruzione dell'oggetto 'A' in questo caso? Intendo alcune regole simili a RVO. – Mikhail
@Mikhail Non ci credo. RVO non può eliminare completamente la costruzione, può eliminare le costruzioni * intermedie *. – TartanLlama