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:

  • C ++ 03
  • C ++ 98

3
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?
Rob Kennedy

1
Und die Frage wurde erst vor ein paar Minuten gestellt. ( stackoverflow.com/questions/7132440/… )
Mat

1
@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.


1
Nicht meine erwartete Antwort, aber ich denke, es gibt einfach keinen universellen Weg, es herauszufinden.
Jasonline

246

Aus den Bjarne Stroustrup C ++ 0x FAQ :

__cplusplus

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.

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 - 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.

#include<iostream>

int main() {
    if (__cplusplus == 201703L) std::cout << "C++17\n";
    else if (__cplusplus == 201402L) std::cout << "C++14\n";
    else if (__cplusplus == 201103L) std::cout << "C++11\n";
    else if (__cplusplus == 199711L) std::cout << "C++98\n";
    else std::cout << "pre-standard C++\n";
}

8
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?
Colin Hicks

2
Siehe: devblogs.microsoft.com/cppblog/… (TLDR : Geben Sie die Flagge an /Zc:__cplusplus)
Daan Timmer

@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.
A__


7

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.


3
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).

C ++ 0x FAQ von BS



0

Nach einem kurzen Google :

__STDC__und __STDC_VERSION__siehe hier


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:

#if ((defined(_MSVC_LANG) && _MSVC_LANG >= 201703L) || __cplusplus >= 201703L)
     //C++17 specific stuff here
#endif
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.