[Visual C++] meine Compilereinstellungen

Programmiersprachen, APIs, Bibliotheken, Open Source Engines, Debugging, Quellcode Fehler und alles was mit praktischer Programmierung zu tun hat.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

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
  • 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.
      1. bestimmte Warnungen – etwa Verwendung uninitialisierter Variablen – werden damit als Fehler behandelt
      2. Security Cookies gegen Buffer Overflow Exploits werden nicht nur in Funktionen mit char-Arrays hineinkompiliert, sondern fast überall
      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.
       
    • 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 GenerationEnable Minimal Rebuild; ich ziehe es vor.
     
  • 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.
     
  • 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++GeneralMulti-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++GeneralSDL 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.
     
  • 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
     
  • 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
     
  • 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:
      1. Die CRT wird komplett ignoriert. (Das will ich normalerweise auch, weil ich meine eigene mitbringe.)
      2. Die Bibliotheken, die normalerweise das Subsystem mitbringt, werden ignoriert. Also z.B. GDI etc.
      3. Alle #pragma comment lib werden ignoriert.
      4. Kernel32.lib wird nicht ignoriert. Es steht grundsätzlich immer zur Verfügung, unabhängig von Compiler-Einstellungen.
      5. 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!
  • 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).
      Wenn einem das alles nichts sagt, Finger davon lassen.
       
    • 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
     
  • 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.
     
  • 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)
  • 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!)
Ich bin müde. Manifest, und HLSL-Compiler trage ich später nach.
Zuletzt geändert von Krishty am 11.03.2018, 22:19, insgesamt 5-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Schrompf »

Danke schonmal, guter Lesestoff und ich hab ein bissl was gelernt.
Krishty hat geschrieben:(Ich könnte auch ein Property Sheet dafür anlegen, aber dann habe ich wieder eine Abhängigkeit mehr – igitt.)
Ich praktiziere das recht erfolgreich: ich habe ja >15 Projekte im aktuellen Spiel, und habe einen Property Sheet mit eingecheckt, der ein paar Sachen pfad-relativ aufsetzt, so dass ich das ganze Spiel einfach auschecken kann und alle Dependencies mit rausgerollt kommen und out-of-the-box gefunden werden.
Krishty hat geschrieben:[*]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.
Ich setze da immer Multibyte, weil ich UTF8 benutze und nicht UTF16. Das wirkt sich primär mal auf die ganzen WinAPI-Funktionen aus - es gibt die immer in der Geschmacksrichtung DoSomethingA() und DoSomethingW(), und ein transparentes Makro DoSomething(), dass je nach Character Set eine der beiden auswählt. Man kann aber auch einfach manuell spezifizieren, welche man haben will, und nimmt dann natürlich immer die W-Variante, damit der User auch 中国的东西.png öffnen kann.
Krishty hat geschrieben:[*]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.
Edit and Continue ist übrigens der ultimative Life Saver, wenn man was in seinem Spiel fine-tunen will und das nicht in nem komplexen Script-Runtime-Environment steckt. Einfach Breakpoint setzen, bisslwas anpassen, weiterlaufen lassen - so hab ich substanzielle Teile der Splatter-KI entwickelt.

Nebenbei Danke für die Erklärungen zu den ganzen Security-Switches.
Krishty hat geschrieben:[*]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.
Echt? Gut zu wissen.

Krishty hat geschrieben:[*]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 (/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.
Ich linke auch immer statisch, u.A. weil's minimal schneller ist und weil ich dem Nutzer eigentlich keinen Installer aufnötigen will. Steam bringt allerdings ein simples Häkchen für "Visual Studio Runtime" mit, so dass es zumindest dort kein großes Thema ist.
Krishty hat geschrieben: [*]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.
Steht bei mir immer auf Fast, der Unterschied war messbar und recht deutlich. Ist lange her, aber ich habe was im Bereich von 10 bis 20% im Hinterkopf. Sollte man unbedingt auch im Debug-Build setzen, wenn man es setzen will, damit die Mathematik in allen Builds konsistent ist. Wenn was schief geht, will man das auch im Debugger sehen. In der Praxis betrifft das aber eh nur Fälle, in denen mathematisch schon alles FUBAR ist, und mein Gedanke ist: dann isses auch wurscht, was für konkrete Werte die Float-Vars dann annehmen.
Krishty hat geschrieben:In allen Release-Builds, deren Quelltext nicht darauf aufbaut, dass globale/statische Variablen zwingend unterschiedliche Adressen haben: /Gw (ordentliche Größenersparnis)
Echt? Muss ich mal ausprobieren.
Krishty hat geschrieben: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.)[/list]
Verständnis: damit stellt man konkret den Abstand ein, aller wieviel Bytes der Compiler eine Stack Probe platziert?
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
joggel

Re: [Visual C++] meine Compilereinstellungen

Beitrag von joggel »

Danke. Ich habe mir das mal alles kopiert.
Ich habe fast nie etwas geändert an diesen einstellungen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Schrompf hat geschrieben:
Krishty hat geschrieben:[*]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.
Ich setze da immer Multibyte, weil ich UTF8 benutze und nicht UTF16. Das wirkt sich primär mal auf die ganzen WinAPI-Funktionen aus - es gibt die immer in der Geschmacksrichtung DoSomethingA() und DoSomethingW(), und ein transparentes Makro DoSomething(), dass je nach Character Set eine der beiden auswählt. Man kann aber auch einfach manuell spezifizieren, welche man haben will, und nimmt dann natürlich immer die W-Variante, damit der User auch 中国的东西.png öffnen kann.
Jetzt, wo du’s sagst: Es gibt drei Einstellungen.
  • Unicode (setzt UNICODE und _UNICODE)
  • Multi-Byte Character Set (setzt _MBCS und hat AFAIK kein WinAPI-Gegenstück)
  • garnichts (nutzt ANSI)
Weiterhin:
  • Win32-API != C++-Runtime – du kannst dann vielleicht 中国的东西.png mit fopen() oder std::stream öffnen, aber nicht mit CreateFile() (weil das ANSI-Codepage erwartet statt UTF-8)
  • in der C++-Runtime nutzt du mit MBCS nicht die w-Version, sondern die mb-Version (Beispiele)
Schrompf hat geschrieben:
Krishty hat geschrieben: [*]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.
Steht bei mir immer auf Fast, der Unterschied war messbar und recht deutlich. Ist lange her, aber ich habe was im Bereich von 10 bis 20% im Hinterkopf. Sollte man unbedingt auch im Debug-Build setzen, wenn man es setzen will, damit die Mathematik in allen Builds konsistent ist. Wenn was schief geht, will man das auch im Debugger sehen. In der Praxis betrifft das aber eh nur Fälle, in denen mathematisch schon alles FUBAR ist, und mein Gedanke ist: dann isses auch wurscht, was für konkrete Werte die Float-Vars dann annehmen.
Mein Code baut teilweise darauf auf, dass INF/NaN dem Standard entsprechend weiterverarbeitet wird (weil ich’s gern als Schalter oder Fallback einsetze) – und da zerhaut einem /fp:fast dann die ganze Logik :(
Schrompf hat geschrieben:
Krishty hat geschrieben: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.)[/list]
Verständnis: damit stellt man konkret den Abstand ein, aller wieviel Bytes der Compiler eine Stack Probe platziert?
Ja, genau. Es gibt keine Option, das abzuschalten; daher stellt man es auf einen Wert, der in der Praxis nicht erreicht wird.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

P.S., Schrompf: Die MSDN-Seiten sind sich ziemlich einig darin, dass Multi-Byte Character Set aus Legacy-Gründen auf zwei Bytes limitiert ist – kannst du Pile of Poo Emoji.png öffnen? (Sorry, Symbol wird vom Board nicht unterstützt …)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Schrompf »

Weiß ich nicht. fopen() benutze ich nicht auf Windows, sondern nehme _wfopen(), was ich dann halt mit nem UTF16-String befüttern muss. Zum Glück ist boost::filesystem überaschend pragmatisch, was das angeht, und bietet das bereits stressarm an. fopen() nutzt nach meinem Wissen gar kein UTF, sondern arbeitet auf der aktuellen Windows-CodePage, was ja mal sowas von 2003 ist und außerdem auf modernen lokalisierten Betriebssystemen mehr oder minder nix mehr öffnen kann.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Naja; wenn du eh wfopen() nutzt, dann bringt dir Multi-Byte Character Set aber nicht viel – was machst du sonst mit UTF-8? Benutzernamen, Highscores?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Schrompf
Moderator
Beiträge: 4831
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Schrompf »

Alle Strings sind UTF8, und alle WinAPI-Calls sind eh handausgewählt. Die Einstellung ist eigentlich inzwischen irrelevant in meinen Projekten, glaube ich... ich hab das nur seit Jahren auf dieser Option und mir keine Gedanken mehr gemacht.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von dot »

Wie schon gesagt wurde hat MBCS mit UTF-8 (leider) nix zu tun da die von dem entsprechenden Switch betroffenen Mechanismen (afaik) kein UTF-8 supporten. MBCS ist afaik rein prinzipiell nur relevant wenn du die Ansi-Varianten der WinAPI verwendest, was heutzutage niemand tun sollte. Windows verwendet aus historischen Gründen native UTF-16, die Ansi-Varianten der APIs sind lediglich Wrapper die einfach ihre Argumente erst nach Unicode konvertieren. Der imo "korrekte" Weg ist den Schalter einfach auf Unicode zu belassen und im Falle der WinAPI immer explizit die Unicode APIs zu verwenden...
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Wie gesagt hat MBCS nichts mit der Win32-API zu tun sondern ausschließlich mit der CRT.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von dot »

Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Heiliges Surrogate Pair, du hast recht! Mir war nicht klar, dass man UTF-8 als Eingangs-Codepage schalten kann. Man lernt nie aus …
https://msdn.microsoft.com/en-us/library/windows/desktop/dd374081%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396 hat geschrieben:While Unicode-enabled functions in Windows use UTF-16, it is also possible to work with data encoded in UTF-8 or UTF-7, which are supported in Windows as multibyte character set code pages.
(Natürlich rate ich weiterhin streng davon ab, andere als die Unicode-Funktionen zu nutzen – die werden seit 2005 kaum noch erweitert.)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Ich habe mal meine Linker-Optionen ergänzt. Verdammt, das sind ja noch mehr als die Compiler-Optionen!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: [Visual C++] meine Compilereinstellungen

Beitrag von kaiserludi »

Krishty hat geschrieben: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.
Ich handhabe das so, dass ich einfach ein vorhandenes Projekt kopiere, umbenenne, alle Source- und Headerdateien rausschmeiße, und dann von dieser Ausgangslage aus nach Bedarf die Einstellungen anpasse, die sich tatsächlich unterscheiden, wo es sich anbietet auch per Autoreplace, nachdem ich das Projekt in einem Texteditor geöffnet habe.
So sind die Einstellungen, die bei allen Projekten übereinstimmen, immer gleich gesetzt und ich kann sie nicht vergessen. Außerdem sparts die Arbeit, dass alles manuell zu setzen. Gerade bei vielen utnerschiedlichen Configs und vielen Einstellungen, die sich je nach Config unterscheiden, braucht man doch sonst Stunden.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von dot »

Eine bessere Lösung wäre wohl, ein entsprechendes .props File anzulegen und einfach in jedes neue Projekt zu importieren. Wenn du manuell eine .vcxproj Datei kopierst, dann musst auf jeden Fall auch bedenken, manuell eine neue GUID für das Projekt zu generieren und entsprechend im Project File auszutauschen, sonst gibt's potentiell Probleme spätestens sobald du mal mehr als ein solches Projekt in der selben Solution haben willst. Und den Default Project Namespace willst du vermutlich auch anpassen...
kaiserludi
Establishment
Beiträge: 467
Registriert: 18.04.2002, 15:31

Re: [Visual C++] meine Compilereinstellungen

Beitrag von kaiserludi »

dot hat geschrieben:Eine bessere Lösung wäre wohl, ein entsprechendes .props File anzulegen und einfach in jedes neue Projekt zu importieren. Wenn du manuell eine .vcxproj Datei kopierst, dann musst auf jeden Fall auch bedenken, manuell eine neue GUID für das Projekt zu generieren und entsprechend im Project File auszutauschen, sonst gibt's potentiell Probleme spätestens sobald du mal mehr als ein solches Projekt in der selben Solution haben willst. Und den Default Project Namespace willst du vermutlich auch anpassen...
Die GUID wir von VS automatisch geändert, sobald man das neue Projekt in die Solution mit dem existenten einfügt.
Default Project Namespace? Ist das eine C# Einstellung? Ich rede von C++ Projekten. Um die gehts in diesem Thread ja.
"Mir ist auch klar, dass der Tag, an dem ZFX und Developia zusammengehen werden der selbe Tag sein wird, an dem DirectGL rauskommt."
DirectGL, endlich ist es da
:)

"According to the C++ standard, it's "undefined". That's a technical term that means, in theory, anything can happen: the program can crash, or keep running but generate garbage results, or send Bjarne Stroustrup an e-mail saying how ugly you are and how funny your mother dresses you." :shock:[/size]
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von dot »

kaiserludi hat geschrieben:Die GUID wir von VS automatisch geändert, sobald man das neue Projekt in die Solution mit dem existenten einfügt.
Ok, cool, das wusste ich nicht. Dann lag ich da wohl falsch^^
kaiserludi hat geschrieben:Default Project Namespace? Ist das eine C# Einstellung? Ich rede von C++ Projekten. Um die gehts in diesem Thread ja.
C++ Projekte haben sowas auch. Bin mir ehrlich gesagt selbst nicht sicher was genau den verwendet, vermutlich C++/CLI oder C++/CX Zeug...
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Das größere Problem ist, dass dauernd irgendwas kaputtgeht. Irgendwann kann man z.B. das Toolset nicht mehr ändern oder bestimmte Dateien nicht mehr löschen oder MASM nicht mehr aktivieren – wenn man das Projekt komplett neu anlegt, mit identischen Einstellungen, geht es wieder. Passiert teils auch mit automatischem Update bei neuer Visual Studio-Version.

Dazu trägt auch bei, dass Visual Studio sehr fehlertolerant mit Projektdateien umgeht. Teils kann man falsche Pfade reinschreiben und Visual Studio findet die betreffenden Dateien trotzdem. Nur beim Build kracht’s dann.

Dot hat schon recht damit, dass props der sauberere Weg wären. Allerdings wäre das eine zusätzliche Abhängigkeit, und eine recht fiese dazu (eine fehlende Props-Datei aus dem Projekt zu kriegen ist nichts, was ein Anfänger mal schnell meistert). Die Props müssten also irgendwo in Projektnähe abgelegt werden, und dann bin ich wieder genau da, wo ich vorher war.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von dot »

Ich versteh das Problem nicht ganz, .props file einfach neben das Projekt gelegt und fertig!? Mach ich andauernd, funktioniert wunderprächtigst...
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

… dann verlieren sie den Vorteil, dass man sie zentral ändert und die Änderungen überall angenommen werden.

Ungefähr wie ein Header, der nur ein einziges Mal #includet wird.

Aber Zeit beim Erstellen des Projektes würde es mir schon sparen, ja.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Visual Studio 2019 bringt den Schalter /d2FH4 mit, der die Größe der Exception-Handling-Metadaten drastisch reduzieren soll.

Er muss in den Projekteigenschaften der Befehlszeile des Compilers hinzugefügt werden. Standardmäßig ist er nur deshalb nicht an, weil die Anpassungen für die Windows Runtime es nicht mehr ins Release geschafft haben.

Ich nutze keine Exceptions, aber dem einen oder anderen dürfte das eine ganz willkommene Optimierung sein!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

/d2OptimizeHugeFunctions – Visual C++ optimiert funktionen ab einer gewissen Größe nicht mehr (um die Kompilierzeit zu reduzieren). Die entsprechende Warnung muss von Hand aktiviert werden, und nach der Angabe von /d2OptimizeHugeFunctions werden Funktionen jeder Größe voll optimiert.

Ich konnte diese Größe in meinen Tests bisher nicht erreichen, daher hat mir der Schalter noch nichts gebracht.


/Zc:throwingNew korrigiert eine alte Marotte von Visual C++: Ganz ganz früher warf new bei Fehlschlag keine Ausnahme, sondern lieferte NULL zurück. Der Compiler erzeugt seitdem immer extra-Prüfungen – auch in modernen Programmen, in denen new niemals nullptr zurückgibt. Wird /Zc:throwingNew gesetzt, entfällt das und das Programm wird ein kleines Bisschen schneller und kleiner.

Ich nutze eh kein new, darum mir auch dieser Schalter nichts gebracht.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Wieder eine neue Linker-Option gegen Bloat: /nocoffgrpinfo. Entfernt 100–500 B readonly-Daten (je nach Umfang des Programms). Nur nutzen, falls ihr kein PGO einsetzt.

Erklärung: Ca. 2015 hat Visual Studio angefangen, einen Verweis auf die PGO-Datenbank in die Executable einzubetten. Die wird wohl für die Datensammlung bei Profile-Guided-Optimization benötigt. Das Ding ist, dass Visual C++ diesen Verweis in die Executable einbettet, sogar wenn PGO deaktiviert ist. Fragt mich nicht, warum.

Den PGO-Verweis erkennt ihr an Strings in der Executable, die nach Section Identifiers aussehen – etwa .text$mn oder .rdata$zzzdbg. Virustotal listet das mitunter als Debug-Information auf.

/nocoffgrpinfo hält den Linker davon ab, diese Daten einzubetten.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
udok
Beiträge: 40
Registriert: 01.02.2022, 17:34

Re: [Visual C++] meine Compilereinstellungen

Beitrag von udok »

Manchmal ist auch /Bd hilfreich, das zeigt an mit welchen Optionen der cl1 und cl2 intern aufgerufen wird, inklusive der vordefinierten Makros.

Die Option /Bt zeigt an, wie lange das Kompilieren dauert.

Option /Bv gibt die Pfade und Versionen der vom Compiler verwendeten Dlls an.

Bei hartnäckigen Fehlern im Zusammenhang mit Makros hilft /E, das gibt die Ausgabe vom Preprozessor nach stdout.

Die Option /stdIncludes zeigt die inkludierten Files mit absolutem Pfad an.

Die Option /link /verbose:lib zeigt die Libs an, mit denen der Linker arbeitet.
udok
Beiträge: 40
Registriert: 01.02.2022, 17:34

Re: [Visual C++] meine Compilereinstellungen

Beitrag von udok »

Die Option /Zl unterbindet meistens das Einfügen von Linker Direktiven in das Object File.
Das ist nützlich, wenn man nicht mit den Standard-DLLs der verwendeten VS Installation linken möchte.

Bei hartnäckigen Fällen hilft auch die Linker Option /nod, die die Default Libs ignoriert.

Für deterministische Builds ohne Timestamp hilft /brepro
Benutzeravatar
Krishty
Establishment
Beiträge: 8227
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [Visual C++] meine Compilereinstellungen

Beitrag von Krishty »

Oh ja, /Zl verwende ich auch oft, wenn die Codebase bezüglich der Bibliotheken nur Wildwuchs hat!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten