2014-02-06 15 views
22

Wenn Sie Exceptions ausschalten, indem Sie mit -fno-exceptions kompilieren, werden alle Funktionen berücksichtigt, die nicht zum Beispiel durch std::move_if_noexcept berücksichtigt werden, oder müssen Sie trotzdem Funktionen deklarieren?Sind alle Funktionen "noexcept", wenn Ausnahmen deaktiviert sind?

+0

Viele Funktionen [möglicherweise noch Ausnahmen] (http://stackoverflow.com/questions/6049563/with-fno-exceptions-what-happens-with-new-t) trotz der Kompilierung mit '-Fno-Exceptions' – Praetorian

+0

http://gcc.gnu.org/onlinedocs/libstdc++/manual/using_exceptions.html sagt nicht viel darüber, ich bin mir nicht sicher, ob das die definitive Referenz ist. –

+4

Jemand hat [gefragt] (http://comments.gmane.org/gmane.comp.compilers.clang.devel/30992) ziemlich genau die gleiche Frage auf der Clam-Mailing-Liste, und die Antwort lautet: * Das Kompilieren mit '-fno-exceptions' ist nicht das Gleiche wie das Spezifizieren von' noexcept' für alle Funktionen *. – Praetorian

Antwort

20

Die -fno-exceptions verhindert das Auslösen von Ausnahmen, aber es kann nicht verhindern, dass Ausnahmen aus Bibliotheken ausgelöst werden.

Zum Beispiel wird als nächstes Beispiel beendet wegen nicht abgefangene Ausnahme:

#include <vector> 

int main() 
{ 
    std::vector<int> v{1,2,3,4,5,6}; 

    return v.at(55); 
} 

Aber nächstes Beispiel wird nicht kompiliert, da die -fno-exceptions Option:

int main() 
{ 
    throw 22; 
} 

Es scheitert mit:

g++ -std=c++11 -g -Wall -Wextra -fno-exceptions ./garbage.cpp 
./garbage.cpp: In function ‘int main()’: 
./garbage.cpp:4:8: error: exception handling disabled, use -fexceptions to enable 
    throw 22; 

Von this article, Doing without chapter:

Benutzercode, der C++ Schlüsselwörter wie throw verwendet, versuchen, und fangen produzieren Fehler selbst wenn der Benutzer Code enthalten libstdC++ Header und Konstrukte wie basic_iostream verwenden.


Auf der anderen Seite, noexcept markiert das Verfahren als ein Verfahren, das keine Ausnahmen werfen ist. Jede ausgelöste Ausnahme ruft std::terminate auf (siehe [except.terminate]/2 im C++ - Standard).

Nächstes Beispiel:

struct A 
{ 
    void foo() noexcept 
    { 
     throw 33; 
    } 
}; 

int main() 
{ 
    A a; 
    try 
    { 
     a.foo(); 
    } 
    catch(...) 
    { 
    } 
} 

endet mit:

terminate called after throwing an instance of 'int' 
Aborted (core dumped) 

Zum Schluss: das Verhalten ist ganz anders, wenn Sie -fno-exceptions verwenden und wenn Sie die Funktion als noexcept markieren.


Obwohl ich mein ganzes Projekt mit -fno-Ausnahmen (aus anderen Gründen) kompilieren muss ich noch bewegen Konstrukteuren einen Umzug assigment Betreiber noexcept erklären, damit für std :: move_if_noexcept semantische bewegen?

Wenn Sie diese Option verwenden, werden die Funktionen nicht automatisch als noexcept markiert. Sie müssen es manuell tun. Der Compiler darf solche Änderungen nicht vornehmen.

Wenn eine solche Änderung zulässig wäre, würde this example verschiedene Ausgaben erzeugen.

+0

Ich weiß, dass das Verhalten ganz anders ist. Meine Frage ist: Obwohl ich mein ganzes Projekt mit '-fno-exceptions' kompiliere (aus anderen Gründen), muss ich Move Constructors trotzdem eine move assigment operators deklarieren, um move semantic für std :: move_if_noexcept zu aktivieren. – TNA

+1

@TNA Ok, also habe ich den Punkt missverstanden. Hoffentlich editiert es korrigiert –

Verwandte Themen