[Visual C++] meine Compilereinstellungen
Verfasst: 16.01.2018, 23:24
Bei jedem Projekt, das ich anlege, muss ich die Release-Einstellungen auf’s Neue vornehmen und dauernd vergesse ich dabei was – darum sammle ich meine Einstellungen hier. Dann könnt ihr direkt mitlesen; vielleicht hilft es euch.
(Ich könnte auch ein Property Sheet dafür anlegen, aber dann habe ich wieder eine Abhängigkeit mehr – igitt.)
Alles rot markierte unterscheidet sich bei mir von den Voreinstellungen.
General
C/C++
Linker
(Ich könnte auch ein Property Sheet dafür anlegen, aber dann habe ich wieder eine Abhängigkeit mehr – igitt.)
Alles rot markierte unterscheidet sich bei mir von den Voreinstellungen.
General
- Windows SDK Version
Jedes SDK ist mit jeder Windows-Version kompatibel – wenn dort das 10er-SDK ausgewählt ist, bedeutet das also nicht, dass die Anwendung nur auf Windows 10 liefe. Neue Features brauchen aber logischerweise neue SDKs – eine D3D-12.1-App für den Windows Store muss also auch mit dem neuesten SDK kompiliert werden. Für meine Projekte reicht meistens das 8.1er SDK (ältere finde ich nicht).
Achtung: Der HLSL-Compiler ist seit einigen Jahren Teil des Windows SDKs. Neue SDKs bieten also Bugfixes und verbesserte Optimierung, falls das Projekt Shader enthält! - Output Directory
unwichtig
- Intermediate Directory
unwichtig
- Target Name
unwichtig
- Target Extension
unwichtig
- Extensions to Delete on Clean
unwichtig
- Build Log File
unwichtig
- Platform Toolset
Bestimmt die Version vom Visual C++-Compiler und von der Visual C++ Runtime Library, mit der das Projekt kompiliert/gelinkt wird. Generell gilt: Neueste Version ist beste Version.
Ausnahme 1: Falls das Projekt unter Windows XP laufen muss, muss eine XP-kompatible Toolset-Version ausgewählt werden (die modernen Toolsets funktionieren nur ab Vista; Details hier). Die Ausnahme von der Ausnahme: Projekte, die keine CRT nutzen, können mit jeder Toolset-Version unter XP laufen, sofern die Linker-Einstellungen angepasst werden (siehe unten).
Ausnahme 2: Falls der Quelltext nur mit einer bestimmten Visual C++-Version kompatibel ist, könnt ihr sie hier auswählen.
- Enable Managed Incremental Build
keine Ahnung
- Configuration Type
Falls eine EXE kompiliert wird, kann das Feld zu <inherit from parent or project defaults> zurückgesetzt werden.
- Use of MFC
Use Standard Windows Libraries ist die nette Umschreibung für „ich will keine MFC“.
- Character Set
Ob die Unicode-Version der Win32-API und der C++ Runtime genutzt werden soll, oder die ANSI-Version. Für ANSI gibt es heutzutage keinen Grund mehr, darum Use Unicode Character Set auswählen. Das definiert die Makros UNICODE und _UNICODE.
Ausnahme: Wenn das Projekt weder die Windows-Header nutzt, noch die C++-Runtime, dann kann das Feld zu <inherit from parent or project defaults> zurückgesetzt werden.
- Common Language Runtime Support
No Common Language Runtime Support ist die nette Umschreibung für „ich will keine C#-Syntaxerweiterungen in meinem C++-Code benutzen“.
- .NET Target Framework Version
unwichtig
- Whole Program Optimization
Use Link Time Code Generation für Release-Builds. Alles andere wäre Idiotie.
- Windows Store App Support
… spricht für sich
C/C++
- General
- Additional Include Directories
unwichtig
- Additional #using Directories
unwichtig
- Debug Information Format
<inherit from parent or project defaults> bzw. Program Database (/Zi) für Release-Builds.
<inherit from parent or project defaults> bzw. Program Database for Edit And Continue (/ZI) für Debug-Builds, falls man Edit & Continue nutzen möchte.
C7 Compatible (/Z7) erlaubt, die Debug-Informationen direkt in die EXE/DLL/LIB einzubetten, statt eine zusätzliche PDB zu haben – aber Vorteile hat das nicht.
- Common Language Runtime Support
unwichtig
- Consume Windows Runtime Extension
unwichtig
- Suppress Startup Banner
Ob beim Kompilieren im Output-Fenster die Compiler-Version und das Copyright von Microsoft angezeigt werden. <inherit from parent or project defaults> bzw. Yes /nologo.
- Warning Level
selbsterklärend; bei mir immer 4
- Treat Warnings As Errors
selbsterklärend
- Warning Version
Falls ihr Code habt, der für eine alte Visual C++-Version geschrieben wurde, und nun mit einer neuen Version massig neue Warnungen schmeißt, kann man hier auf das alte Warnverhalten zurückschalten.
unwichtig
- Diagnostics Format
Wer Fehler und Warnungen ähnlich Clang/GCC ausgegeben haben möchte, kann das hier einstellen.
- SDL checks
Aktiviert den Microsoft-Sicherheitsstandard fürs Kompilieren.- bestimmte Warnungen – etwa Verwendung uninitialisierter Variablen – werden damit als Fehler behandelt
- Security Cookies gegen Buffer Overflow Exploits werden nicht nur in Funktionen mit char-Arrays hineinkompiliert, sondern fast überall
- Multi-Processor Compilation
Kompiliert die Quelldateien nebenläufig statt hintereinander. Kein Einfluss auf Code-Qualität, aber deutlich kürzere Kompilierzeiten. Inkompatibel mit C/C++ → Code Generation → Enable Minimal Rebuild; ich ziehe es vor.
- Additional Include Directories
- Optimization
- Optimization
Disabled in Debug-Builds.
Minimize Size (/O1) oder Maximize Speed (/O2) in Release-Builds. Probiert beides aus; manchmal ist der kleine Code schneller (Caches!).
Achtung: Nicht Full Optimization (/Ox) benutzen – auch wenn es besser als Maximize Speed (/O2) klingt, optimiert es schlechter.
- Inline Function Expansion
<inherit from parent or project defaults> bzw. default, da das automatisch durch die Optimierungseinstellung geregelt wird.
Nur manuell überschreiben wenn man weiß, was man tut.
- Enable Intrinsic Functions
Yes (/Oi) in Debug- und Release-Builds. Bewirkt, dass SSE-Intrinsics & Co. tatsächlich entsprechende CPU-Anweisungen erzeugen. Sonst werden sie durch nicht-SSE-Befehle emuliert. Wird leider nicht durch die Optimierung gesteuert. Auch in Debug-Versionen nützlich weil große Leistungsverbesserung mit SSE-Code, und hereinsteppen und debuggen kann man die Dinger ja sowieso nicht.
- Favor Size or Speed
<inherit from parent or project defaults>
unwichtig; habe keine Veränderung in der Code Generation feststellen können (nur aktiv bei benutzerdefinierter Optimierungsstufe?)
- Omit Frame Pointers
<inherit from parent or project defaults>, da das automatisch durch die Optimierungseinstellung geregelt wird (normalerweise an, obwohl sich das Default anders liest).
Nur manuell überschreiben wenn man weiß, was man tut – nicht mit x64 kompatibel; Leistungsverbesserung mit x86, kann aber Call Stacks schwerer analysierbar machen.
- Enable Fiber-Safe Optimizations
<inherit from parent or project defaults>, da das keine wirkliche Optimierung ist. Betrifft Programme, die Fibers einsetzen und dafür Fiber-local Storage brauchen. Wem das nichts sagt, der sollte auch nicht an der Einstellung herumpfuschen.
- Optimization
- Preprocessor
unwichtig
- Code Generation
- Enable String Pooling
<inherit from parent or project defaults>, da es über die Optimierung gesteuert wird. Identische Strings werden dabei zusammengefasst (im Rahmen des C++-Standards, also so lange ihre Adressen bedeutungslos sind).
Achtung: Falls der Compiler sich mal beschwert, dass das Programm im Debug-Build zu groß zum Kompilieren ist, könnt ihr damit die Größe drücken. Andererseits solltet ihr dann aber auch den Job wechseln.
- Enable Minimal Rebuild
<inherit from parent or project defaults>
Kompiliert nur die Funktionen neu, die geändert wurden. Mittlerweile veraltet (aktuelle Visual C++-Versionen tun das ähnlich auch ohne diese Option) und nicht mit C/C++ → General → Multi-Processor Compilation kompatibel. - Enable C++ Exceptions
Achtung: Irreführender Titel: Exceptions (C++ wie Win32) funktionieren mit jeder Option weiter!
Steuert, in welchen Fällen C++-Destruktoren aufgerufen werden. Wer kein RAII nutzt, kann das auf No stellen (und weiterhin Exceptions schmeißen und fangen, ohne dass Destruktoren aufgerufen werden). Spart enorm viel Platz und bringt geringe Geschwindigkeitsverbesserungen. Die anderen Abstufungen betreffen vor allem die Abschätzung, an welchen Stellen im Programm Exceptions auftreten dürfen (ergo, an welchen Stellen der Compiler Destruktor-Aufrufe einkalkulieren muss) und sollten nur verändert werden, wenn man genau weiß, was man tut.
- Smaller Type Check
Baut in jeden Cast Prüfungen ein, ob Daten verloren gehen (etwa, wenn 999 zu char gecastet wird). Leistungseinbuße beträchtlich. In Debug-Builds habe ich’s immer an; in Release-Builds immer aus.
- Basic Runtime Checks
Baut in alle Funktionen Prüfungen ein, ob der Call Stack intakt und alle Variablen vor der Benutzung initialisiert sind. Unterbricht das Programm, falls nicht. Leistungseinbuße beträchtlich. In Debug-Builds habe ich’s immer an; in Release-Builds immer aus.
- Runtime Library
Steuert, ob das Programm für die C++-Runtime von der Visual C++ Redistributable abhängig ist (dynamisch eingebunden, Multi-threaded DLL (/MD) und Multi-threaded Debug DLL (/MDd)) oder ob die C++-Runtime ins Programm kopiert wird (statisch eingebunden, Multi-threaded (/MT) und Multi-threaded Debug (/MTd)).
Ich persönlich linke statisch, weil ich meine eigene C++-Runtime habe und für die Handvoll Funktionen kein extra-Setup beim User vornehmen möchte.
- Struct Member Alignment
Sollte man nur anfassen, wenn man weiß, was man tut. Ich nutze immer 1 B (Diskussion).
- Security Check
Kompiliert in jede Funktion, die char-Arrays nutzt, Security Cookies gegen Buffer Overflow Exploits hinein. Wird durch C/C++ → General → SDL checks verstärkt.
Ich persönlich hab’s nur in Debug-Versionen an, weil ich an Buffer Overflows anders herangehe. Wer nichts über das Thema weiß, sollte es an lassen.
- Control Flow Guard
Wieder was gegen Exploits. Wer nichts über das Thema weiß, sollte es nicht anrühren.
- Enable Function-Level Linking
Release-Build: <inherit from parent or project defaults>, da es über die Optimierung gesteuert wird.
Debug-Build: an, falls man Edit & Continue nutzen möchte.
- Enable Parallel Code Generation
unwichtig
- Enable Enhanced Instruction Set
In 32-Bit-Builds immer mindestens Streaming SIMD Extensions 2 (/arch:SSE2), da so ziemlich jede CPU seit 1999 kompatibel ist (betrifft ja nicht nur Gleitkommazahlen, sondern auch Conditional Move & Co.).
- Floating Point Model
Fast (/fp:fast) kann zwar die Leistung deutlich verbessern, aber auch die Rechenergebnisse stark verändern. Wer sich nicht richtig mit Gleitkommazahlen befasst hat, oder im Programm NaN/INF benutzt, sollte hier nichts anrühren.
- Enable Floating Point Exceptions
unwichtig
- Create Hotpatchable Image
unwichtig
War ursprünglich dafür gedacht, Programme während des Betriebs zu patchen (durch spezielle Prologe vor Funktionen, die zu Wartebefehlen umgeleitet werden konnten). Microsoft selber hat es nur ein Mal benutzt und dann nie wieder.
- Enable String Pooling
- Language
- Disable Language Extensions
Veraltet. Nutzt Conformance mode direkt darunter.
- Conformance mode
Yes (/permissive-) deaktiviert viele Microsoft-Erweiterungen und schaltet den Compiler in den standardkonformen Modus. Nutzt es schonmal; in einer kommenden Version wird es standardmäßig eingeschaltet.
- Treat WChar_t As Built in Type
unwichtig (Steinzeit)
- Force Conformance in For Loop Scope
unwichtig (sofern ihr nicht gerade S.T.A.L.K.E.R. kompiliert)
- Remove unreferenced code and data
Veraltet?
- Enforce type conversion rules
unwichtig (Visual C++ 2010 hatte einen Bug mit rvalue-Referenzen)
- Enable Run-Time Type Information
Falls ihr keinen dynamic_cast auf polymorphe Klassen und keinen typeid-Operator nutzt, könnt ihr das auf No (/GR-) schalten.
TODO: Interessanterweise bewirkt das sogar bei Programmen ohne polymorphe Klassen eine Erparnis von acht Bytes; prüfen!
- OpenMP Support
unwichtig (und wird bald abgeschafft)
- C++ Language Standard
ISO C++ Latest Draft Standard (/std:c++latest), weil die Standardeinstellung immer hinterherhängt (AFAIK läuft das aktuelle Visual C++ 2017 standardmäßig auf C++’14)
- Enable C++ Modules (experimental)
unwichtig
- Disable Language Extensions
- Precompiled Headers
nutze ich nicht
- Output Files
rühre ich nicht an
- Browse Information Files
Mariaherrgott wer braucht das
- Advanced
rühre ich nicht an
- Command Line
In 32-Bit-Release-Builds: /d2noftol3 (Diskussion)
In allen Release-Builds, deren Quelltext nicht darauf aufbaut, dass globale/statische Variablen zwingend unterschiedliche Adressen haben: /Gw (ordentliche Größenersparnis)
In allen Release-Builds, die keine lokalen Arrays/Datentypen >= 4096 B nutzen oder sie strikt seriell initialisieren: /Gs1000000000 (normalerweise verbaut der Compiler Code, der den Stack in 4-KiB-Schritten abtastet, um korrektes Wachstum zu garantieren – die Option schaltet die sog. Stack Probes aus.)
Linker
- General
- Output File
<inherit from parent or project defaults>
Schlicht der Name der EXE/DLL, die erzeugt wird.
- Show Progress
<inherit from parent or project defaults> bzw. Not Set
Besonders detaillierte Statusmeldungen während des Linkvorgangs (Verbose Output)
- Version
TODO
- Enable Incremental Linking
Verkürzt die Kompilierzeit indem nur neu gelinkt wird, was sich auch tatsächlich geändert hat.
Die finale Version, die verteilt wird, muss entweder via Rebuild kompiliert werden oder mit /INCREMENTAL:NO – sonst kann inkrementalles Linking bewirken, dass Datenleichen aus vorherigen Kompiliervorgängen in der ausgelieferten EXE bleiben.
- Suppress Startup Banner
<inherit from parent or project defaults>
Zeigt während des Linkvorgangs Name und Version des Linkers an. Keine Auswirkung auf das Kompilat.
- Ignore Import Library
<inherit from parent or project defaults>
- Register Output, Per-User Redirection
<inherit from parent or project defaults>
Falls ihr COM-Server programmiert, können sie damit nach dem Kompilieren direkt in die COM-Registry eingetragen werden. Self Registration ist aber mittlerweile deprecated.
- Additional Library Directories
- Link Library Dependencies
- Use Library Dependency Inputs
<inherit from parent or project defaults>
TODO; nutze ich atm nicht
- Link Status
<inherit from parent or project defaults>
Damit zeigt der Linker einen Fortschrittsbalken im Output-Fenster an.
- Prevent Dll Binding
- Treat Linker Warning As Errors
- Force File Output
TODO; nutze ich atm nicht
- Create Hot Patchable Image
siehe Beschreibung von C/C++ → Code Generation → Create Hotpatchable Image
- Specify Section Attributes
TODO; nutze ich atm nicht
- Output File
- Input
- Additional Dependencies
- Ignore All Default Libraries
Die beiden muss ich zusammen abhandeln. Erstmal ist der Name Ignore All Default Libraries scheiße gewählt: Damit werden nicht irgendwelche Standardbibliotheken ignoriert, sondern alle, mit Ausnahmen:- Die CRT wird komplett ignoriert. (Das will ich normalerweise auch, weil ich meine eigene mitbringe.)
- Die Bibliotheken, die normalerweise das Subsystem mitbringt, werden ignoriert. Also z.B. GDI etc.
- Alle #pragma comment lib werden ignoriert.
- Kernel32.lib wird nicht ignoriert. Es steht grundsätzlich immer zur Verfügung, unabhängig von Compiler-Einstellungen.
- Alle Bibliotheken unter Additional Dependencies werden ebenfalls nicht ignoriert.
- Ignore Specific Default Libraries
TODO
- Module Definition File
Falls ihr dem Linker noch ganz klassisch eine Liste exportierter Funktionen auf den Weg geben möchtet statt __declspec(dllexport) zu verwenden, könnt ihr hier die Datei angeben. Dafür gibt es mehrere Gründe:- Visual C++ warnt, wenn COM-Funktionen keine privaten Exporte sind.
- Ihr möchtet Ordinals unterstützen, etwa für Abwärtskompatibilität.
- …
- Add Module to Assembly
- Embed Managed Resource File
- Force Symbol References
- Delay Loaded Dlls
- Assembly Link Resource
TODO
- Manifest File
- Generate Manifest
Wenn man kein Manifest braucht (ich bei vielen meiner kleinen Tools), kann man es hier deaktivieren. Spart eine Ressource im Modul und damit Platz.
- Manifest File
Wenn man sein eigenes Manifest abliefern möchte statt eines automatisch erzeugten, kann man das hier einstellen. Mich nervt oft das Whitespace (Leerzeichen statt Tabs sind Verschwendung), darum mache ich das manchmal.
- Additional Manifest Dependencies
Wenn man z.B. eine bestimmte Version der Common Controls laden möchte, aber #pragma comment linker für schmutzig hält.
- Allow Isolation
Unverzichtbar für Plugin-Entwicklung
TODO:
https://blogs.msdn.microsoft.com/oldnew ... 0/?p=97195
https://blogs.msdn.microsoft.com/talagr ... directory/
- Enable User Account Control
Eigentlich könnte man es abschalten, wenn man mit Standardrechten auskommt, aber es signalisiert Windows darüber hinaus, dass man UAC-kompatibel ist.
TODO: pros & cons abwägen
- UAC Execution Level
asInvoker (/level='asInvoker'), um keine Admin-Rechte zu fordern.
- UAC Bypass UI Protection
kA
- Achtung:
Hier ist leider nur ein Bruchteil der Manifest-Einstellmöglichkeiten. Den Rest im Manifest Tool nicht vergessen. Insbesondere Manifest Tool → Input and Output → DPI Awareness!
- Generate Manifest
- Debugging
TODO: Hier muss ich mich erst einarbeiten; insbesondere in die verschiedenen Debug Information Formats
- System
- SubSystem
Windows NT wurde mit dem Ziel entwickelt, andere APIs als NTs eigene zu emulieren (insbesondere Win32 und POSIX). Die Emulation wird durch DLLs realisiert, die mit der Anwendung laden. Die sinnvollen Wahmöglichkeiten:- Windows (/SUBSYSTEM:WINDOWS) startet die Anwendung mit Kernel32.dll, damit sie als Win32-Anwendung läuft.
- Console (/SUBSYSTEM:CONSOLE) startet die Anwendung ebenfalls als Win32-Anwendung, allerdings mit Anbindung an eine Konsole.
- Native (/SUBSYSTEM:NATIVE) startet die Anwendung mit ntdll.dll, damit sie rein mit NT laufen kann (etwa beim Boot des Systems).
- Minimum Required Version
Die Windows-Version, die zum Start der Anwendung vorausgesetzt wird. Visual Studio wählt unsichtbar den Standardwert 6.0 (Windows Vista). Meine Programme laufen z.B. meist theoretisch auch auf Windows XP und mit dem Wert 5.01 kann ich sie für den XP-Loader freischalten. Sonst kommt die wenig aussagekräftige Meldung Foo.exe is not a valid Win32 application bzw. Foo.exe ist keine gültige Win32-Anwendung.
- Heap Reserve Size
- Heap Commit Size
TODO
- Stack Reserve Size
… falls einem mal der Stack ausgeht, kann man ihn hier vergrößern. Standardeinstellung ist 1048576 (ein Megabyte).
- Stack Commit Size
… falls man ganz sicher weiß, dass die Anwendung eine bestimmte Menge Stack nutzt, und sich die Allokationen in 4-KiB-Schritten sparen möchte (siehe Stack Probes bei C/C++ → Command Line oben), kann man hier den Adressraum im Voraus reservieren.
- Enable Large Addresses
In 32-Bit-Builds ruhig an; vergrößert den Adressraum, falls die Anwendung auf einem 64-Bit-Betriebssystem läuft.
Achtung: Immer kompatibel programmieren!
- Terminal Server
TODO
- Swap Run From CD
- Swap Run From Network
Windows lädt Code erst aus Modulen, sobald er auch benutzt wird. Das kann Stottern verursachen, falls eine Anwendung auf einer CD oder im Netzwerk liegt.
Beispiel: Computerspiel startet von CD. Häufig genutzter Code wird geladen. Spieler spielt zehn Minuten. CD-Laufwerk bremst wegen Inaktivität runter. Spieler erreicht Endgegner. Code mit der KI des Endgegners war bisher ungenutzt und muss erst aus der EXE geladen werden. CD-Laufwerk braucht drei Sekunden, um wieder hochzudrehen. Spieler verflucht Drecksspiel.
Noch schlimmer ist das auf dem Netzwerk, wenn die Verbindung abbricht.
Diese Option ist ein Befehl an den Kernel, das Modul erst komplett in die Auslagerungsdatei zu kopieren und dann von dort aus auszuführen.
- Driver
uninteressant
- SubSystem
- Optimization
- References
Löscht Funktionen und Daten, die nicht benutzt werden. Bringt eine ordentliche Größenersparnis.
Setzt Function-Level Linking voraus, das wird aber von den Optimierungen mitgebracht.
- Enable COMDAT Folding
Fasst identische Funktionen zusammen – insbesondere Getter verschiedener Klassen. Template-Metaprogrammierung wird damit überhaupt erst möglich (sonst wäre sie wegen der Größenexplosion unpraktikabel).
Sorgt dafür, dass man beim Debugging verwirrt guckt, wenn der Debugger in getZombieHealth() springt statt in getGreenIntensity(), denn beide erzeugen zufällig die selben Maschinenbefehle.
Das kann leicht den C++-Standard verletzen, der voraussetzt, dass Funktionen unterschiedliche Adressen haben. AFAIK werden Funktionen von der Optimierung ausgeschlossen, wenn deren Adressen genommen werden; aber irgendwo gab es da noch andere Fälle, in denen das nicht 100 % standardkonform ist.
Die enorme Code-Ersparnis ist mir aber wichtiger.
- Function Order
Für optimale Cache-Nutzung sollten Funktionen, die zeitnah aufgerufen werden, auch nebeneinander in der EXE liegen. In 16-Bit-Tagen war das sogar eine der größten Optimierungen überhaupt. Heute komplett von Profile-Guided Optimization verdrängt, die das automatisch für euch tut.
- Profile Guided Database
guckt euch an, wie PGO funktioniert
- Link Time Code Generation
Use Link Time Code Generation (/LTCG)
Seit Visual Studio 2017 haben sie dort als Standard Fast Link Time Code Generation eingestellt. Die ist viel viel schneller (optimiert nur neu, was sich geändert hat), aber weniger effizient. Achtet drauf.
- References
- Embedded IDL
Nur für COM-Entwicklung interessant
- Windows Metadata
Igittigittigitt
- Advanced
- Entry Point
Aus C++-Sicht startet das Programm mit main(). Tatsächlich startet das Programm aber mit der C++ Runtime, und die initialisiert globale Variablen und holt die Kommandozeile, bevor sie an main() weiterreicht. Mit dieser Option lässt sich das ändern.
Erlaubt außerdem das Erzeugen von Chimären-Modulen, die EXE und DLL zugleich sind.
Fun Fact: Eigener Einsprungspunkt bedeutet automatisch, dass die CRT nicht mehr gelinkt wird.
- No Entry Point
Erlaubt das Erzeugen von Chimären-Modulen, die keine ausführbaren DLLs sind.
- Set Checksum
Damit bekommt der PE-Header eine Checksumme verpasst, die der Loader beim Start überprüft.
Praktisch nutzlos.
- Base Address
- Randomized Base Address
- Fixed Base Address
Standardadresse, an die der Code geladen werden soll. Unsichtbare Standardwerte hier erklärt; dem Artikel gemäß bevorzuge ich auch 0x10000.
Falls die Adresse bereits belegt ist oder Randomized Base Address nicht auf No (/DYNAMICBASE:NO) steht, wird das Modul wo anders geladen. Das ist heutzutage der gewollte Fall, denn zufällige Basisadressen erschweren Angriffe (Adress Space Layout Randomization). Die ASLR-Einstellung betrifft nur dieses eine Modul. Sie hat keine Auswirkungen auf andere Module.
Falls man das Ganze komplett abstellt (Fixed Base Address auf Yes (/FIXED)), ist die EXE nicht mehr relocatable. Damit wir auch kein Relocation Table erzeugt und man spart ein paar Prozent Größe. Bei DLLs geht man dann aber das Risiko ein, dass sie bei ungünstiger Konstellation gar nicht mehr geladen werden können.
- Data Execution Prevention (DEP)
Yes (/NXCOMPAT)
Kostenlose Angriffserschwernis: Verhindert, dass globale Variablen von Angreifern missbraucht werden können, um Code auszuführen.
Setzt voraus, dass ihr keine Thunks nutzt (oder sie zumindest auf dem Heap anlegt statt als globale Variablen).
Ihr solltet auch Data Execution Prevention in eurer Windows-Installation aktivieren, obwohl alte Spiele damit reihenweise crashen und als Ausnahmen eingestellt werden müssen.
- Turn Off Assembly Generation
- Unload delay loaded DLL
- Nobind delay loaded DLL
- Import Library
kA TODO
- Merge Sections
Damit könnt ihr Abschnitte ähnlicher Eigenschaften zusammenfassen. Wird heute kaum noch gebraucht.
- Profile
- CLR Thread Attribute
- CLR Image Type
- Key File
- Key Container
- Delay Sign
- CLR Unmanaged Code Check
Zeug, das niemand braucht.
- Error Reporting
Keine Auswirkung aufs Kompilat – sagt nur, was der Linker tun soll, wenn er abstürzt. (In euren Nightlies wollt ihr das sicher anders handhaben als auf der Produktivmaschine.)
- SectionAlignment
War früher eine Optimierungsmöglichkeit; ist heute aber optimal voreingstellt (512 B).
- Preserve Last Error Code for PInvoke Calls
hnnnnnngh
- Image Has Safe Exception Handlers
kA; keine Auswirkungen hier (außer scheiß Fehlermeldungen mit MASM)
- Entry Point
- Command Line
- Nicht den kompletten Pfad der Debug-Symbole in die EXE kopieren, sondern nur den Dateinamen: /pdbaltpath:%_PDB% (aber nur in Release-Builds; siehe Hinweis hier)
- Keine nutzlosen PGO-Referenzen ins Executable schreiben: /nocoffgrpinfo (natürlich nicht, falls ihr PGO tatsächlich nutzt!)