Dieser Post wurde [wpstatistics stat=pagevisits time=total id=534] mal angesehen.
Folgend eine Liste meiner bevorzugten und vielleicht (?) besten Visual Studio Settings für modernes C++ basierend auf meinen Erfahrungen und Auswertungen. Jedes erwähnte Setting ist mit einer kurzen Erklärung versehen.
Ich behandle nur „Release“ Builds – und ich verwende Visual Studio 2022, aber dieselben Settings sollten auch für Visual Studio 2019 gültig sein. Unveränderte Settings lasse ich aus (es sei denn, sie sind trotzdem wichtig um erwähnt zu werden).
Alle Settings werden im „Property Page“ Dialog des Projektes vorgenommen.
Wir starten mit der Dialog Seite:
“Configuration Properties” ➜ “Advanced”
★ Setze “Character Set” auf “Use Unicode character Set”
Dies ist Windows-spezifisch. Aber wenn wir jemals mit der WIN32 API in Berührung kommen sollten, dann wollen wir als Default die „wide character“ Variante nutzen und auf gar keinen Fall etwas mit der ANSI-Variante und Code Pages zu tun haben.
Nächste Seite:
“Configuration Properties” ➜ “C/C++” ➜ “General”
★ Setze “SDL checks” auf “Yes”
Dies aktiviert Sicherheitschecks, welche zu extra Warnungen oder sogar Compile-Fehlern führen, wenn gefährliche Sachen verwendet werden. Zum Beispiel wird der folgende Code nicht kompilieren und wir müssen ihn so abändern, dass das Gewünschte explizit ausgedrückt wird.
unsigned int x = 1;
unsigned int foo = -x; // compile error b/c x is unsigned and foo is still unsigned but use unary minus.
// must make it explicit:
unsigned int foo = static_cast<unsigned int>( - static_cast<signed int>(x) ); // now compiles.
★ Setze “Multi-processor compilation” auf “Yes”
Hole das meiste aus deiner Maschine heraus.
“Configuration Properties” ➜ “C/C++” ➜ “Optimization”
★ Setze “Whole Program Optimization” auf “Yes”
Hole das meiste aus deinem Code heraus!
“Configuration Properties” ➜ “C/C++” ➜ “Preprocessor”
★ Setze “Use Standard Conforming Preprocessor” auf “Yes”
Selbstverständlich wollen wir einen standardkonformen Präprozessor verwenden und keinen mit Microsoft Dialekt.
“Configuration Properties” ➜ “C/C++” ➜ “Code Generation”
★ Setze “Enable String pooling” auf “Yes”
Wenn du oft die gleichen String Literale mehr als einmal im Code verwendest, dann wird dieses Setting es so optimieren, dass jedes mehrfache String Literal nur einmal auftaucht und dieselbe Adresse verwendet. Das ist sehr nützlich, wenn z.B. oft „Yes“ und „No“ oder „true“ und „false“ usw. vorkommt.
★ Setze “Enable C++ Exceptions” auf “Yes”
C++ ohne Exceptions ist nicht C++.
“Configuration Properties” ➜ “C/C++” ➜ “Language”
★ Setze “Disable Language extension” auf “No”
Diese Entscheidung mag kontrovers aussehen. Wollen wir nicht standardkonform sein?
Natürlich wollen wir! Aber dieses Setting ist sehr, SEHR speziell. Es ist für den C Compiler und nicht für den C++ Compiler. Wenn man echte C Dateien mit .c Endung kompiliert, dann wird ein Setting auf „Yes“ den C Compiler im strikten C89(!) Modus betreiben. Aber wenn man C++ Dateien kompiliert, kommt ein komplett anderer Modus im Compiler zum Einsatz: C++11 und neuer erfordert C99 Feature-Level. Aus diesem Grund ist es für C++ Code absolut NICHT empfohlen dieses Setting mit „Yes“ zu verwenden. Andernfalls kann es zu unerwarteten Verhalten führen! (Siehe Microsoft Dokumentation: https://learn.microsoft.com/en-us/cpp/build/reference/za-ze-disable-language-extensions )
★ Setze “Treat wchar_t as built-in type” auf “Yes” (ist idR. jetzt Default.)
wchar_t
sollte ein eigenständiger Typ sein und nicht unsigned short
.
★ Setze “Force Conformance in for loop scope” auf “Yes” (ist jetzt bereits Default.)
Die öffnenden Klammern der For-Schleife beginnen einen neuen Scope für die deklarierten Variablen, so wie es im C++ Standard spezifiziert ist. Wenn man die Variable noch nach der Schleife benötigt, dann muss man diese außerhalb der Schleife deklarieren.
★ Setze “Enforce Type conversion rules” auf “Yes”
Dieses Setting deaktiviert VS spezifische Casting-Regeln, welche nicht C++11 konform sind.
★ Setze “Enable Run-Time Type information” auf “Yes”
Natürlich wollen wir RTTI haben. Andernfalls können wir nicht dynamic_cast und typeid verwenden.
★ Setze “C++ Language standard” auf “ISO C++20”
Verwende die neueste und beste C++ Standard Version. Anm.: Beachte, dass du mindestens Visual Studio 2022 17.2 benötigst, um C++20 inklusive der gefixten Standard Defect Reports zu haben. (Für Visual Studio 2019 benötigst du mindestens 16.11.14.)
Ich empfehle „C++ Latest“ nur für Experimente zu aktivieren und nicht für echte Projekte.
★ Setze “C Language standard” auf “ISO C17”
Verwende den neuesten und besten C Standard.
★ Setze “Conformance Mode” auf “Yes”
Dies ist wichtig um verschiedene VS spezifische Sprachdialekte zu deaktivieren. Dieses Setting wird insbesondere das Übergeben von anonymen Objekten als non-const Referenzen als Parameter verhindern, welches nicht standardkonform ist und sehr viele Compile-Fehler unter anderen Compilern auf anderen Plattformen produziert.
struct Object {}
void test( Object & rObj ) // non const reference
{
}
// invoke function with anonymous/temporary object.
test( Object{} ); // compiles without conformance mode but should not!
“Configuration Properties” ➜ “C/C++” ➜ “Command Line”
Füge folgendes zur Kommandozeile hinzu:
★ /Zc:__cplusplus
Dieses setzt den korrekten Wert im Macro __cplusplus, so dass man es einfach zum Testen nutzen kann, anstatt VS spezifische Macros dafür zu verwenden.
★ /utf-8
Dein Source Code ist UTF-8. Damit kannst du Unicode Zeichen in Kommentaren und String Literale verwenden (und dabei Plattform unabhängig bleiben!).
Das war es auch schon. Habe ich etwas Wichtiges vergessen? Lass doch einen Kommentar da, auch wenn es dir gefallen hat, oder zu einem Setting eine andere Meinung hast.
Fröhliches Programmieren! 😊