MS Code Analyse
-
Kann ich so blöd sein? Wo soll ich denn noexcept hinschreiben?
-
@tormen_bln sagte in MS Code Analyse:
- C26455/C26439 ist keine harte Regel, sondern bloss was MS gut & richtig findet. Kann man so sehen, muss man aber nicht. Das "may not" im Text der Warning ist also übertrieben, die korrekte Formulierung wäre eher "should not".
- C26455/C26439 wird u.A. bei Default-Konstruktoren erzeugt wenn diese nicht
noexceptmarkiert sind. - Die Frage wo du - im Zusammenhang mit C26455/C26439 in Zeile 11 - in deinem Code noch
noexcepthinschreiben sollte kann man mit "nirgends" beantworten. Denn: DerWinAPIDefault-Konstruktor kann Exceptions werfen, da er einen std::string mit nicht-leerem Inhalt initialisieren muss. Was nichtnoexceptgeht.
Wenn du die Warning vermeiden willst bleiben dir folgende Möglichkeiten:
a) Entferne den
WinAPIDefault-Konstruktor. D.h. er muss nen Parameter bekommen der keinen Default-Wert hat. Der naheliegende Kandidat wäre der "last error" Wert. Den Aufruf vonGetLastErrorimWinAPIKonstruktor halte ich sowieso für schlechten Stil. Grund: wenn manGetLastErrornicht direkt sofort nach dem fehlgeschlagenen Aufruf macht, kann man kaum sicherstellen dass dazwischen nicht ein weiterer WinAPI Aufruf gemacht wurde, der evtl. den "last error" Wert ändert. D.h. man kann kaum sicher stellen dass man den richtigen Fehlercode bekommt. Den User zu zwingenGetLastErrorselbst aufzurufen könnte man also sogar als Verbesserung ansehen (ich sehe das so).
Wenn du unbedingt einen Convenience-Helper möchtest derGetLastErroraufruft und dir ein damit initialisiertesWinAPIException Objekt gibt kannst du das ja leicht machen, z.B. indem duWinAPIeine statische FunktionfromLastErrorgibst die einWinAPIObjekt zurückgibt und ca. so aussehen könnte:class WinAPI ... { // ... static WinAPI fromLastError() { auto const errorCode = ::GetLastError(); // Das sollte auf jeden Fall die erste Anweisung in dieser // Funktion bleiben, sonst besteht wieder die Gefahr dass du den falschen Wert bekommst return WinAPI{ errorCode }; } // ... };b) Ändere deine Exception-Klasse so, dass die Fehlermeldung erst zusammengebaut wird wenn
getMessagebzw.getDetailedDescriptionaufgerufen werden. Dann könntest du statt einenstd::stringzu initialisieren imWinAPIDefault-Konstruktor einfach nur den Fehlercode im Objekt ablegen (wasnoexceptgeht, ist ja bloss einDWORD), undFormatMessageerst ingetMessagebzw.getDetailedDescriptionaufrufen.Eine weitere Beobachtung: Exceptions sollten immer noexcept-kopierbar sein. Sonst kann es passieren dass beim Fangen einer Exception wieder eine Exception erzeugt wird, was dann aua ist. Die einfachste Möglichkeit das zu erreichen, ist alles was beim Kopieren Allokationen erfordert (bzw. allgemein alles was beim Kopieren Exceptions werfen kann) in eine kleine Hilfs-
structzu packen, und in der Exception-Klasse dann nur einenshared_ptr<HelperStruct const>zu halten. Dashared_ptrnoexceptzu kopieren ist löst das das Problem. Bzw. wenn gar nichts gehalten werden muss was beim Kopieren werfen könnte (so wie hier wenn du Variante (b) wählst), gibt es sowieso kein Problem.Noch ein letzter Punkt: sei mit
noexceptsehr vorsichtig. Wenn du an eine Funktionnoexceptdranschreibst, dann garantierst du damit dass aus der Funktion keine Exceptions rausfliegen. Anders als beiconstoder ähnlichen Dingen hilft dir der Compiler allerdings nicht dabei dieses Versprechen zu halten, indem er dir einen Fehler um die Ohren wirft wenn dunoexceptwo dazuschreibst "wo es nicht hingehört". Statt dessen wird das Programm fehlerfrei übersetzt, und wenn während der Laufzeit dann eine Exception aus einernoexceptFunktion rausfliegen würde (weil du nicht aufgepasst hast), dann wird an der Stelle statt dessen einfach dein Programm abgebrochen -std::terminate. Schwupps-weg, einfach so.
Möglicherweise wird dir der Static Analyzer bei solchen Fehlern eine Warnung geben (-> C26447), aber verlassen sollte man sich mMn. nicht unbedingt darauf.ps:
c) Markiere deinen Default-Konstruktor alsnoexcept(false). Das sollte den Static Analyzer von Visual Studio wissen lassen dass du dir darüber im Klaren bist dass der Konstruktor nichtnoexceptist, und die Warnung sollte nicht mehr kommen. Zumindest steht das so hier https://developercommunity.visualstudio.com/content/problem/236762/c-code-analysis-warning-c26439-this-kind-of-functi.html beschrieben.
-
Dieser Beitrag wurde gelöscht!
-
@hustbaer Vielen, vielen Dank und sorry, dass meine Antwort so spät kommt. Das ist mal eine Aussage, mit der ich etwas anfangen kann. Auch die Tipps zum schlechten Stil, danke nochmals. Ich werde das alles umbauen und bin somit diese Warnungen erstmal los. Gibt ja noch weitere, die bearbeitet werden wollen

Auch Dank an alle anderen, die versucht haben, mir zu helfen.
MfG Torsten