web-dev-qa-db-fra.com

Quelle norme C ++ est la norme par défaut lors de la compilation avec g ++?

J'ai un morceau de code qui ressemble à ce qui suit. Disons que c'est dans un fichier nommé 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;
}

Sur une fenêtre, si je tape dans le cmd la commande g++ example.cpp, ça va échouer. Je pense que c'est une longue liste d'erreurs principalement due au fait que l'éditeur de liens se soit plaint de ne pas pouvoir convertir de string en const char*.

Mais si je lance le compilateur en utilisant un argument supplémentaire comme ceci: g++ -std=c++17 example.cpp, il se compilera et fonctionnera sans problème.

Que se passe-t-il lorsque j'exécute l'ancienne commande? Je devine un défaut version le standard du compilateur C++ est appelé, mais je ne sais pas lequel? Et en tant que programmeur/développeur, devrais-je toujours utiliser cette dernière commande avec l'argument supplémentaire?

30
Manuel

Si votre version de g++ est postérieur à 4.7 Je pense que vous pouvez trouver la version par défaut de la norme C++ supportée de la manière suivante:

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

Un exemple de ma machine:

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

Quelques références:

40
Michael Burr

Je devine qu'une version par défaut du compilateur C++ est appelée, mais je ne sais pas laquelle?

Ceci est seulement concevable en lisant la documentation de votre version de compilateur particulière.

Si vous utilisez un récent GCC , je vous recommande tout d'abord de comprendre quelle version êtes-vous en utilisant en cours d'exécution

g++ -v

ou

g++ --version

et puis se référer à la version de la version particulière de GCC. Par exemple, pour GCC 7, lisez modifications de GCC 7 etc

Sinon, lancez

g++ -dumpspecs

et déchiffrer le soi-disant par défaut fichier de spécification .

BTW, vous pouvez vous assurer (par exemple dans certains de vos fichiers d’en-tête communs) que C++ est au moins C++ 17 en codant

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

et je recommande en fait de le faire de cette façon.

PS En fait, imaginez que C++ 98 et C++ 17 soient deux langues différentes (par exemple, comme Ocaml4 et C++ 11 le sont). Demandez à votre utilisateur de disposer d’un compilateur prenant en charge une norme de langage définie (par exemple, C++ 11), et non une version particulière de GCC . Lisez aussi à propos de gestionnaires de paquets .

10

Je pense qu’il est possible de dire en consultant la page de manuel (du moins pour g ++):

Sous la description de -std, la page de manuel répertorie tous les standards C++, y compris les dialectes GNU. Sous un standard spécifique, il est indiqué de manière assez discrète, This is the default for C++ code. _ (il existe une déclaration analogue pour les normes C: This is the default for C code.).

Par exemple, pour g++/gcc version 5.4.0, cela est répertorié sous gnu++98/gnu++03, alors que pour g++/gcc version 6.4.0, cela est répertorié sous gnu++14.

9
AnInquiringMind

Taper g++ --version dans votre commande, Shell révélera la version du compilateur et vous pourrez en déduire le standard par défaut. Donc, vous ne pouvez pas dire directement mais vous pouvez déduire, avec quelques efforts.

Les compilateurs sont supposés to #define__cplusplus qui peut être utilisé pour extraire le standard qu’ils prétendent implémenter au moment de la compilation; mais beaucoup ne le font pas encore.

(Et n'oubliez pas d'inclure tous les en-têtes de bibliothèque standard C++ dont vous avez besoin: où est celui pour std::string par exemple? Ne comptez pas automatiquement sur l’implémentation de votre bibliothèque standard C++, y compris sur d’autres en-têtes - vous n’écrivez pas en C++ portable.)

5
Bathsheba

Vous pouvez également vérifier avec gdb

  1. $ g++ example.cpp -g Compile le programme avec l'option -g pour générer les informations de débogage
  2. $ gdb a.out Programme de débogage avec gdb
  3. (gdb) b main Mettre un point d'arrêt à main
  4. (gdb) run Exécuter le programme (fera une pause au point d'arrêt)
  5. (gdb) info source

Imprime quelque chose comme:

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.

Il y a la norme utilisée par le compilateur: Producer is GNU C++14

Si vous recompilez votre programme en utilisant -std=c++11 _ (par exemple), gdb le détecte: Producer is GNU C++11

4
Benitok

la page de manuel de g ++ indique en fait quelle est la norme par défaut pour le code C++.

Utilisez le script suivant pour afficher la partie pertinente:

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

Par exemple, dans RHEL 6 g ++ (GCC) 4.4.7 20120313 (Red Hat 4.4.7-23), la sortie:

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

Et dans Fedora 28 g ++ (GCC) 8.1.1 20180502 (Red Hat 8.1.1-1), la sortie:

       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

Votre question concerne spécifiquement les compilateurs gnu. Il est donc probablement préférable de l’étiqueter correctement plutôt que simplement C++ et C++ 11.

Votre code sera compilé avec tous les compilateurs (et les bibliothèques associées) compatibles avec C++ 11 et versions ultérieures.

La raison en est que C++ 11 a introduit un constructeur std::ifstream Qui accepte un const std::string &. Avant C++ 11, un std::string Ne pouvait pas être passé, et il serait nécessaire dans votre code de passer filename.c_str() plutôt que filename.

Selon les informations fournies par gnu, https://gcc.gnu.org/projects/cxx-status.html#cxx11 , gcc.4.8.1 a été la première version à prendre entièrement en charge le C++ 11. Sur la ligne de commande, g++ -v Demande à g++ De vous indiquer son numéro de version.

Si vous creusez dans la documentation, vous pourrez peut-être trouver la version/Subversion qui prenait en charge suffisamment de fonctionnalités pour que votre code - tel que donné - soit compilé. Mais une telle version supporterait certaines fonctionnalités de C++ 11 et pas d’autres.

Puisque Windows n'est pas distribué avec g ++, vous aurez la version que quelqu'un (vous?) A choisi d'installer. Aucune version par défaut de g ++ n'est associée à votre version de Windows.

3
Peter