Alle GCC 4.8.4, 4.9.3, 5.3.0 passieren die Tests für std::exception
(für jeden von -std = C++ 11/1J/14/1Z/17-Optionen, wo verfügbar):Sind der Kopierkonstruktor und die Kopierzuordnung von std :: runtime_error noexcept?
static_assert(std::is_nothrow_copy_constructible<std::exception>::value, "test exception");
static_assert(std::is_nothrow_copy_assignable <std::exception>::value, "test exception");
namespace std { class exception { public: exception() noexcept; exception(const exception&) noexcept; exception& operator=(const exception&) noexcept; virtual ~exception(); virtual const char* what() const noexcept; }; }
Leider alle oben nicht auf den folgenden static_assert
s Compiler:
was in Ordnung ist, da std::exception
hat spezielle Mitglieder (C++ 14 18.8.1) noexcept
static_assert(std::is_nothrow_copy_constructible<std::runtime_error>::value, "test runtime_error");
static_assert(std::is_nothrow_copy_assignable <std::runtime_error>::value, "test runtime_error");
Die Norm enthält nur die folgenden über std::runtime_error
in 19.2.6:
namespace std { class runtime_error : public exception { public: explicit runtime_error(const string& what_arg); explicit runtime_error(const char* what_arg); }; }
Aber nichts gesagt über die noexcept
ness des anderen (implizit besondere deklariert) Mitglieder noch die Speicherimplementierung Anforderungen von what_arg
.
der Standard (14 C++) sagt der folgende in 15.4/14:
Ein Vererbungs Konstruktor (12.9) und ein implizit deklarierte spezielle Mitgliedsfunktion (Ziffer 12), eine Ausnahme-Spezifikation. Wenn f ein ererbender Konstruktor oder ein implizit deklarierter Standardwert Konstruktor ist, Konstruktor kopieren, Konstruktor verschieben, Destruktor, Kopie Zuweisungsoperator oder Zuweisungsoperator verschieben, gibt seine implizite Ausnahmespezifikation die Typ-ID T genau dann an, wenn T ist erlaubt durch die Ausnahmespezifikation einer direkt aufgerufenen Funktion durch die implizite Definition von f; f erlaubt alle Exceptions, wenn eine Funktion es direkt aufruft erlaubt alle Exceptions, und f hat die Exception-Spezifikation noexcept (true), wenn jede Funktion, die es direkt aufruft, keine Ausnahmen erlaubt.
und die folgend in 18.8.1/2:
Jede Standard-Bibliothek Klasse T, die von Klassen Ausnahme leitet soll haben eine öffentlich zugängliche Copykonstruktor und einen öffentlich zugänglichen Kopierzuweisungsoperator, tun nicht mit einer Ausnahme beenden.
Da std::runtime_error
aussetzt nicht die Umsetzung der what_arg
Lagerung, wissen wir nicht, ob es (spezielle) Mitglieder sind noexcept oder nicht, so dass die noexceptness von std::runtime_error
‚s Copy-Konstruktor oder kopieren Zuordnung Mitglieder unentscheidbar sind. Unsere einzige Wette ist 18.8.1 oben.
Frage 1/a) Wir betrachten std::runtime_error
Copy Constructor oder kopieren Zuordnung zu noexcept (1, 2). Ist das wahr/State-of-the-Art/Best Practice?
Frage 1/b) Müssen wir dies nicht explizit in der Norm angeben? (Wie in 18.8.2, Klasse bad_exception
)
Frage 1/c) Ist es ein Fehler in GCC, dass es die oben genannten static_sert-Tests nicht besteht?
Frage 2) Wenn der obige Abzug falsch ist, könnte mich jemand auf die Sektion (en) im Standard verweisen, die besagt, dass std :: runtime_error keinen execept Kopierkonstruktor (und Kopierzuweisung) hat? (Oder, wo es heißt, dass sie nicht sind.)
Sind Sie sicher, dass gcc 5.3.0 die Tests für 'std :: runtime_error' nicht besteht? Es scheint, dass [gcc 5.2.0 die Tests besteht] (http://melpon.org/wandbox/permlink/aHDNg8cs7ttnJlaW). – cpplearner
Ich versuchte mit g ++ - 5 (Ubuntu 5.3.0-3ubuntu1 ~ 14.04) 5.3.0 20151204 und es schlägt fehl. –
Hmmmm, es könnte einige Probleme mit meiner GCC 5.3.0-Installation geben, da sie folgendes in /usr/include/c++/5.3.0/stdexcept enthält: #if _GLIBCXX_USE_CXX11_ABI || _GLIBCXX_DEFINE_STDEXCEPT_COPY_OPS runtime_error (const runtime_error &) _GLIBCXX_ssss_USE_NEXCEPT; runtime_error & operator = (const runtime_error &) _GLIBCXX_USE_NOEXCEPT; #endif aber es gab keinen Fehler (beachten Sie, dass ich die Definition _GLIBCXX_ geändert habe) –