web-dev-qa-db-de.com

Gibt es eine Präprozessor-Direktive zur Erkennung von C ++ 11x-Unterstützung?

Wenn Sie Code haben, in dem ich so oft wie möglich C++ 11x-Erweiterungen verwenden möchte, haben Sie jedoch einen Fallback, wenn dies nicht unterstützt wird. Gegenwärtig unterstützen die OSX-Version von GCC und der VisualC-Compiler C++ 11x kaum oder gar nicht. Daher verwende ich:

#if (defined(__Apple__) || (defined(_WIN32)))
   ...fallback code without C++11x ...
#else
   ... code using C++11x ...
#endif

Und das funktioniert, ist aber nicht das Richtige, zumal der gcc-Compiler in MacPorts c ++ 11x unterstützt.

Gibt es ein #define C11X_SUPPORTED Typ Makro? Vielleicht hat etwas nur GCC?

49
Kenneth

__cplusplus Sollte in Compilern vor C++ 11 als 199711L Und in solchen, die C++ 11 unterstützen, als 201103L Definiert werden. Ob dies in der Praxis eine große Hilfe ist, ist eine andere Frage: Die meisten Compiler sind nur zur Hälfte da und sollten es nicht als 201103L Definieren, auch wenn sie die Funktionen unterstützen, an denen Sie interessiert sind. Und das ist nicht ungewöhnlich Ein Compiler, der lügt: Ein Compiler, der es als 199711L definiert und beispielsweise export für Vorlagen nicht unterstützt. Es gibt jedoch keine Standardfunktion für Funktionstests.

Die einfachste Lösung besteht darin, erst dann eine bestimmte neue Funktion zu verwenden, wenn Sie sicher sind, dass alle Compiler diese unterstützen. Sie müssen den Fallback-Code trotzdem schreiben und unterstützen. warum pflegen zwei Versionen. Die einzige Ausnahme von dieser Regel können neue Funktionen sein, die sich auf die Leistung auswirken: ob der Compiler die Verschiebungssemantik unterstützt oder nicht. In solchen Fällen würde ich eine Compiler-abhängige Include-Datei vorschlagen, die Sie selbst auf der Grundlage der Compiler-Dokumentation und persönlicher Tests schreiben. Nur weil der Compiler möglicherweise dokumentiert, dass er eine bestimmte Funktion unterstützt, bedeutet dies nicht, dass die Unterstützung fehlerfrei ist. Erstellen Sie einfach ein Verzeichnis pro Zielcompiler, platzieren Sie diese Datei dort und geben Sie die entsprechende Option -I Oder /I In Ihrem Makefile oder Ihrer Projektdatei an.

Und Ihre Tests sollten in etwa so aussehen:

#ifdef HAS_MOVE_SEMANTICS
...
#endif

anstatt nur auf dem Compiler, der Version oder was auch immer.

52
James Kanze

Sie können den Wert des __cplusplus Makro. Für C++ 11 ist es größer als 199711L.

Also sowas wie

#if __cplusplus > 199711L

#endif
26
Luchian Grigore

Die Bibliothek Boost.Config bietet granulare Präprozessor-Makros , mit denen Sie basierend auf dem Vorhandensein einer bestimmten C++ 11-Funktion bedingt kompilieren können.

(Für einen Compiler muss die C++ 11-Unterstützung nicht alles oder nichts sein. Überlegen Sie sich beispielsweise, wie Microsoft Kirsche, welche C++ 11-Funktionen ausgewählt wurden in Visual Studio 2012 auf der Grundlage dessen, was sie enthalten sollen davon ausgegangen, dass ihre Kunden am meisten davon profitieren würden.)

7
Edward Brey