web-dev-qa-db-de.com

Welcher C ++ - Standard ist der Standard beim Kompilieren mit g ++?

Ich habe einen Code, der wie folgt aussieht. Angenommen, es befindet sich in einer Datei mit dem Namen example.cpp

#include <fstream>
#include <string> // line added after edit for clarity

int main() {
    std::string filename = "input.txt";
    std::ifstream in(filename);

    return 0;
}

Wenn ich unter Windows den Befehl g++ example.cpp In cmd eingebe, schlägt dies fehl. Ich denke, es ist eine lange Liste von Fehlern, die hauptsächlich darauf zurückzuführen sind, dass sich der Linker beschwert, nicht von string nach const char* Konvertieren zu können.

Aber wenn ich den Compiler mit einem zusätzlichen Argument wie dem folgenden ausführe: g++ -std=c++17 example.cpp, Wird er ohne Probleme kompiliert und funktioniert.

Was passiert, wenn ich den vorherigen Befehl ausführe? Ich vermute einen Standard ausführung Standard des C++ Compilers wird aufgerufen, aber ich weiß nicht welche? Und sollte ich als Programmierer/Entwickler immer den letzteren Befehl mit dem zusätzlichen Argument verwenden?

30
Manuel

Wenn Ihre Version von g++ ist später als 4.7. Ich denke, Sie können die Standardversion des C++ - Standards wie folgt finden:

g++ -dM -E -x c++  /dev/null | grep -F __cplusplus

Ein Beispiel von meiner Maschine:

[email protected] ~ $ g++ --version | head -1
g++ (Ubuntu 4.8.4-2ubuntu1~14.04.3) 4.8.4
[email protected] ~ $ g++ -dM -E -x c++  /dev/null | grep -F __cplusplus
#define __cplusplus 199711L

Einige Referenzen:

40
Michael Burr

Ich vermute, dass eine Standardversion des C++ - Compilers aufgerufen wird, aber ich weiß nicht, welche?

Dies ist nur zu erraten, wenn Sie die Dokumentation Ihrer speziellen Compilerversion lesen.

Wenn Sie ein aktuelles GCC verwenden, empfehle ich zunächst zu verstehen, welche Version Sie sind Verwenden durch Laufen

g++ -v

oder

g++ --version

und beziehen Sie sich dann auf die Version der jeweiligen Version von GCC. Lesen Sie zum Beispiel für GCC 7 Änderungen an GCC 7 etc

Alternativ können Sie auch ausführen

g++ -dumpspecs

und entschlüsseln Sie die so genannte Standard spec-Datei .

Übrigens könnten Sie sicherstellen (z. B. in einigen Ihrer gemeinsamen Header-Dateien), dass C++ mindestens C++ 17 ist, indem Sie codieren

 #if __cplusplus < 201412L
 #error expecting C++17 standard
 #endif

und ich empfehle es tatsächlich so zu machen.

PS. Stellen Sie sich C++ 98 und C++ 17 als zwei verschiedene Sprachen vor (z. B. wie Ocaml4 und C++ 11). Fordern Sie Ihren Benutzer auf, einen Compiler zu haben, der einen definierten Sprachstandard (z. B. C++ 11) unterstützt, und keine bestimmte Version von GCC . Lesen Sie auch über Paketmanager .

10

Ich glaube, dass es möglich ist, anhand der Manpage zu sagen (zumindest für g ++):

Unter der Beschreibung von -std, die Manpage listet alle C++ - Standards auf, einschließlich der GNU Dialekte. Unter einem bestimmten Standard wird ziemlich unauffällig angegeben, This is the default for C++ code. (für C-Standards gibt es eine analoge Aussage: This is the default for C code.).

Zum Beispiel für g++/gcc version 5.4.0, dies ist aufgeführt unter gnu++98/gnu++03, während für g++/gcc version 6.4.0, dies ist aufgeführt unter gnu++14.

9
AnInquiringMind

Wenn Sie g++ --version In Ihre Befehls-Shell eingeben, wird die Version des Compilers angezeigt. Daraus können Sie den Standardstandard ableiten. Sie können es also nicht direkt sagen, aber Sie können es mit einigem Aufwand ableiten.

Compiler sind vermutlich zu #define__cplusplus, Die verwendet werden können, um den Standard zu extrahieren, den sie zur Kompilierungszeit implementieren sollen; aber viele machen das noch nicht.

(Und vergessen Sie nicht, alle C++ - Standardbibliotheksheader einzuschließen, die Sie benötigen: Wo ist beispielsweise der für std::string? Verlassen Sie sich dabei nicht automatisch auf Ihre C++ - Standardbibliotheksimplementierung und andere Header schreiben kein portables C++.)

5
Bathsheba

Sie können auch mit GDB überprüfen

  1. $ g++ example.cpp -g Programm mit -g-Flag kompilieren, um Debug-Informationen zu generieren
  2. $ gdb a.out Programm mit gdb debuggen
  3. (gdb) b main Setze einen Haltepunkt an main
  4. (gdb) run Programm ausführen (wird am Haltepunkt angehalten)
  5. (gdb) info source

Druckt etwas aus wie:

Current source file is example.cpp
Compilation directory is /home/xxx/cpp
Located in /home/xxx/cpp/example.cpp
Contains 7 lines.
Source language is c++.
Producer is GNU C++14 6.3.0 20170516 -mtune=generic -march=x86-64 -g.
Compiled with DWARF 2 debugging format.
Does not include preprocessor macro info.

Es gibt den vom Compiler verwendeten Standard: Producer is GNU C++14

Wenn Sie Ihr Programm beispielsweise mit -std=c++11 Neu kompilieren, erkennt gdb es: Producer is GNU C++11

4
Benitok

die g ++ - Manpage zeigt tatsächlich, was der Standard für C++ - Code ist.

Verwenden Sie das folgende Skript, um den relevanten Teil anzuzeigen:

man g++ | col -b | grep -B 1 -e '-std.* default'

In RHEL 6 g ++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23) lautet die Ausgabe beispielsweise:

         gnu++98
           GNU dialect of -std=c++98.  This is the default for C++ code.

Und in Fedora 28 g ++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1) lautet die Ausgabe:

       gnu++1y
           GNU dialect of -std=c++14.  This is the default for C++ code.  The name gnu++1y is deprecated.
4
Ding-Yi Chen

Ihre Frage ist spezifisch für Gnu-Compiler, daher ist es wahrscheinlich besser, sie entsprechend zu kennzeichnen, als nur C++ und C++ 11.

Ihr Code wird mit allen Compilern (und zugehörigen Bibliotheken) kompiliert, die mit C++ 11 und höher kompatibel sind.

Der Grund dafür ist, dass C++ 11 einen Konstruktor std::ifstream Eingeführt hat, der einen const std::string & Akzeptiert. Vor C++ 11 konnte ein std::string Nicht übergeben werden, und es wäre in Ihrem Code erforderlich, filename.c_str() anstelle von filename zu übergeben.

Laut Informationen von gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11 , war gcc.4.8.1 die erste Version, die C++ 11 vollständig unterstützte. In der Befehlszeile zeigt g++ -vg++ Die Versionsnummer an.

Wenn Sie in der Dokumentation stöbern, können Sie möglicherweise die Version/Subversion finden, die zuerst genügend Funktionen unterstützt, damit Ihr Code - wie angegeben - kompiliert werden kann. Eine solche Version würde jedoch einige C++ 11-Funktionen unterstützen, andere nicht.

Da Windows nicht mit g ++ ausgeliefert wird, haben Sie die Version, die jemand (Sie?) Für die Installation ausgewählt hat. Ihrer Windows-Version ist keine Standardversion von g ++ zugeordnet.

3
Peter