Wie bestimme ich die vom Compiler verwendete Version des C ++ - Standards?
114
Wie bestimmen Sie, welche Version des C ++ - Standards von Ihrem Compiler implementiert wird? Soweit ich weiß, sind nachfolgend die Standards aufgeführt, die ich kenne:
Sie haben dieses C ++ markiert , aber zwei der drei von Ihnen aufgelisteten Standards sind keine C ++ - Standards. Für welche Sprache (n) interessieren Sie sich?
@Mat: Aufgesetzt und geschlossen, weil die Frage Müll war und einen anderen willkürlichen Unsinn huckepack hatte. Ich habe es in anständiger Form neu gepostet. Ich würde dieses gerne schließen, wenn es so aussieht, als würde das Original repariert und wiederbelebt, aber ich halte nicht den Atem an.
Leichtigkeitsrennen im Orbit
1
@Mat: Nun, die beste Antwort ist keine statische Liste von Compilern, sondern ein Mittel, um selbst zu bestimmen, was verwendet wird. Hier bitteschön.
Leichtigkeitsrennen im Orbit
1
@Als: Es wird bald sein. Ich verspreche es. Außerdem hat das c++-faqTag keine tatsächliche Voraussetzung "Anzahl der Anfragen", die Sie übergeben müssen. Es geht mehr um das Format und die Allgemeinheit der Sache.
Leichtigkeitsrennen im Orbit
Antworten:
13
Meines Wissens gibt es keinen allgemeinen Weg, dies zu tun. Wenn Sie sich die Header von plattformübergreifenden / mehrere Compiler unterstützenden Bibliotheken ansehen, werden Sie immer viele Definitionen finden, die compilerspezifische Konstrukte verwenden, um solche Dinge zu bestimmen:
/*Define Microsoft Visual C++ .NET (32-bit) compiler */#if (defined(_M_IX86) && defined(_MSC_VER) && (_MSC_VER >= 1300)...#endif/*Define Borland 5.0 C++ (16-bit) compiler */#if defined(__BORLANDC__) && !defined(__WIN32__)...#endif
Sie müssen diese Definitionen wahrscheinlich selbst für alle von Ihnen verwendeten Compiler vornehmen.
In C ++ 0x wird das Makro __cplusplusauf einen Wert gesetzt, der vom aktuellen Wert abweicht (größer als dieser ist) 199711L.
Obwohl dies nicht so hilfreich ist, wie man möchte. gcc(anscheinend seit fast 10 Jahren) hatte diesen Wert auf gesetzt 1, was einen großen Compiler ausschloss , bis er behoben wurde, als gcc 4.7.0 herauskam .
Dies sind die C ++ - Standards und welchen Wert sollten Sie erwarten können __cplusplus:
C ++ Pre-C ++ 98: __cplusplusist1 .
C ++ 98: __cplusplusist199711L .
C ++ 98 + TR1: Dies lautet C ++ 98 und es gibt keine Möglichkeit zu überprüfen, ob ich davon weiß.
C ++ 11: __cplusplusist201103L .
C ++ 14: __cplusplusist201402L .
C ++ 17: __cplusplusist 201703L.
Wenn der Compiler älter sein könnte gcc, müssen wir auf compilerspezifisches Hackery zurückgreifen (ein Versionsmakro ansehen, es mit einer Tabelle mit implementierten Funktionen vergleichen) oder Boost.Config verwenden (das relevante Makros bereitstellt ). Dies hat den Vorteil, dass wir tatsächlich bestimmte Funktionen des neuen Standards auswählen und eine Problemumgehung schreiben können, wenn die Funktion fehlt. Dies wird häufig einer Wholesale-Lösung vorgezogen, da einige Compiler behaupten, C ++ 11 zu implementieren, aber nur einen Teil der Funktionen anbieten.
Leider kann eine genauere Überprüfung auf Funktionen (z. B. einzelne Bibliotheksfunktionen wie std::copy_if) nur im Build-System Ihrer Anwendung durchgeführt werden (Code mit der Funktion ausführen, prüfen, ob sie kompiliert und korrekte Ergebnisse erzielt hat - autoconfist das Werkzeug der Wahl, wenn sie verwendet wird diese Route).
Sieht nicht so aus, als würden Compiler-Anbieter dies aktualisieren - vielleicht warten sie, bis sie vollständig dem Standard entsprechen? ( Stackoverflow.com/q/14131454/11698 )
Richard Corden
2
@prnr: Das mag wahr sein, aber es liegt an dem Benutzer, der die Frage gestellt hat, zu entscheiden, welche Antwort akzeptiert werden soll. Zu dem Zeitpunkt, als die Antwort, die derzeit als akzeptiert markiert ist, veröffentlicht wurde, war sie korrekt, sodass das Originalplakat sie akzeptierte. Dieser Benutzer könnte beschließen, die akzeptierte Antwort zu ändern, ist jedoch möglicherweise nicht mehr auf der Site aktiv. Sehen: meta.stackexchange.com/questions/120568/…
Dan Korn
3
vs2017 gibt den Wert von __cplusplus 199711 an
Al Mamun
5
@AlMamun Microsoft teilweise __cplusplusnur in VS 15.7 behoben . Siehe ihren Visual C ++ Team Blog
Ivan_Bereziuk
1
Der Link zu den FAQ ist unterbrochen.
Gehirnplot
38
Führen Sie den folgenden Code aus, um die Version zu überprüfen.
Es ist lustig, weil in visuellen Studios der Wert von __cplusplus 199711L ist und der von Ihnen veröffentlichte Code c ++ 98 zurückgibt. Ich habe jedoch Funktionen aus c ++ 14 verwendet, einschließlich variabler Vorlagen und decltype (auto). Ist es möglich, dass die falsche Version des Makros implementiert wurde?
@DaanTimmer Ich bin verwirrt von diesem Artikel, er scheint Kenntnisse über die Verwendung der /Zc:__cplusplusFlagge vorauszusetzen . Ich kann nicht einfach, std::cout << /Zc:__cplusplus;weil Doppelpunkte und Schrägstriche natürlich nicht Teil von Variablennamen sein können. Können Sie erklären, wie das geht? Vielen Dank.
Je nachdem, was Sie erreichen möchten, kann Boost.Config Ihnen helfen. Es bietet keine Erkennung der Standardversion, aber Makros, mit denen Sie prüfen können, ob bestimmte Sprach- / Compilerfunktionen unterstützt werden.
Das Überprüfen auf Funktionen ist wahrscheinlich sowieso eine bessere Idee als das Überprüfen von Standardversionen. Nur wenige Compiler unterstützen alles von einem Standard, aber wenn sie alle die begrenzte Anzahl von Funktionen unterstützen, die Sie benötigen, spielt es keine Rolle, ob die restlichen Funktionen eines bestimmten Standards implementiert sind und ordnungsgemäß funktionieren.
Rob Kennedy
4
__cplusplus
In C ++ 0x wird das Makro __cplusplus auf einen Wert gesetzt, der sich vom aktuellen 199711L unterscheidet (größer als dieser ist).
Ob __STDC__definiert ist und welchen Wert es hat, wird in C ++ implementierungsdefiniert.
Rob Kennedy
@ Rob: Ja, das ist es. @Tor: Ich habe es in VC ++ 2005 versucht, aber es heißt, STDC ist eine nicht deklarierte Kennung. Es wird jedoch als eines dieser vordefinierten Makros aufgeführt. Allerdings STDC_VERSION nicht vorhanden ist .
Jasonline
Hier erfahren Sie, welche Version der Programmiersprache C vom Compiler unterstützt wird. Es sagt nichts über die Version der unterstützten C ++ - Sprache aus.
Dan Moulding
0
Normalerweise sollten Sie __cplusplusdefine verwenden, um c ++ 17 zu erkennen, aber standardmäßig definiert der Microsoft Compiler dieses Makro nicht richtig, siehe https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - Sie benötigen Sie können entweder die Projekteinstellungen so ändern, dass sie den /Zc:__cplusplusSchalter enthalten, oder Sie können die folgende Syntax verwenden:
c++-faq
Tag keine tatsächliche Voraussetzung "Anzahl der Anfragen", die Sie übergeben müssen. Es geht mehr um das Format und die Allgemeinheit der Sache.Antworten:
Meines Wissens gibt es keinen allgemeinen Weg, dies zu tun. Wenn Sie sich die Header von plattformübergreifenden / mehrere Compiler unterstützenden Bibliotheken ansehen, werden Sie immer viele Definitionen finden, die compilerspezifische Konstrukte verwenden, um solche Dinge zu bestimmen:
Sie müssen diese Definitionen wahrscheinlich selbst für alle von Ihnen verwendeten Compiler vornehmen.
quelle
Aus den Bjarne Stroustrup C ++ 0x FAQ :
Obwohl dies nicht so hilfreich ist, wie man möchte.
gcc
(anscheinend seit fast 10 Jahren) hatte diesen Wert auf gesetzt1
, was einen großen Compiler ausschloss , bis er behoben wurde, als gcc 4.7.0 herauskam .Dies sind die C ++ - Standards und welchen Wert sollten Sie erwarten können
__cplusplus
:__cplusplus
ist1
.__cplusplus
ist199711L
.__cplusplus
ist201103L
.__cplusplus
ist201402L
.__cplusplus
ist201703L
.Wenn der Compiler älter sein könnte
gcc
, müssen wir auf compilerspezifisches Hackery zurückgreifen (ein Versionsmakro ansehen, es mit einer Tabelle mit implementierten Funktionen vergleichen) oder Boost.Config verwenden (das relevante Makros bereitstellt ). Dies hat den Vorteil, dass wir tatsächlich bestimmte Funktionen des neuen Standards auswählen und eine Problemumgehung schreiben können, wenn die Funktion fehlt. Dies wird häufig einer Wholesale-Lösung vorgezogen, da einige Compiler behaupten, C ++ 11 zu implementieren, aber nur einen Teil der Funktionen anbieten.Das Stdcxx-Wiki enthält eine umfassende Matrix für die Compiler-Unterstützung von C ++ 0x-Funktionen (wenn Sie es wagen, selbst nach den Funktionen zu suchen).
Leider kann eine genauere Überprüfung auf Funktionen (z. B. einzelne Bibliotheksfunktionen wie
std::copy_if
) nur im Build-System Ihrer Anwendung durchgeführt werden (Code mit der Funktion ausführen, prüfen, ob sie kompiliert und korrekte Ergebnisse erzielt hat -autoconf
ist das Werkzeug der Wahl, wenn sie verwendet wird diese Route).quelle
__cplusplus
nur in VS 15.7 behoben . Siehe ihren Visual C ++ Team BlogFühren Sie den folgenden Code aus, um die Version zu überprüfen.
quelle
/Zc:__cplusplus
)/Zc:__cplusplus
Flagge vorauszusetzen . Ich kann nicht einfach,std::cout << /Zc:__cplusplus;
weil Doppelpunkte und Schrägstriche natürlich nicht Teil von Variablennamen sein können. Können Sie erklären, wie das geht? Vielen Dank.Je nachdem, was Sie erreichen möchten, kann Boost.Config Ihnen helfen. Es bietet keine Erkennung der Standardversion, aber Makros, mit denen Sie prüfen können, ob bestimmte Sprach- / Compilerfunktionen unterstützt werden.
quelle
C ++ 0x FAQ von BS
quelle
Verwenden Sie es
__cplusplus
wie empfohlen. Verwenden SieZc:__cplusplus
zum Aktivieren nur den Hinweis für den Microsoft-Compiler__cplusplus
Quelle https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/
quelle
Nach einem kurzen Google :
__STDC__
und__STDC_VERSION__
siehe hierquelle
__STDC__
definiert ist und welchen Wert es hat, wird in C ++ implementierungsdefiniert.Normalerweise sollten Sie
__cplusplus
define verwenden, um c ++ 17 zu erkennen, aber standardmäßig definiert der Microsoft Compiler dieses Makro nicht richtig, siehe https://devblogs.microsoft.com/cppblog/msvc-now-correctly-reports-__cplusplus/ - Sie benötigen Sie können entweder die Projekteinstellungen so ändern, dass sie den/Zc:__cplusplus
Schalter enthalten, oder Sie können die folgende Syntax verwenden:quelle