Quelle est la différence dans GCC entre -std = gnu++0x et-std=c++0x et lequel devrait être utilisé?

J'ai des problèmes avec <stdint.h> lors de l'utilisation de -std=c++0x dans GCC 4.4.3 (pour Android):

// using -std=c++0x
#include <stdint.h>
uint64_t value;  // error: 'uint64_t' does not name a type

Mais utiliser -std=gnu++0x fonctionne:

// using -std=gnu++0x
#include <stdint.h>
uint64_t value;  // OK

Est <stdint.h> incompatible avec C++0x?

27
demandé sur spatulamania 2011-02-27 23:30:29

1 réponses

Pour autant que je sache, je pense que cela pourrait être argumenté un bug d'implémentation (ou en fait, puisque C++0x n'est pas publié, pas un bug en soi mais une implémentation incomplète de L'état actuel de la norme à venir).

Voici pourquoi, en se référant à n3225 pour le comportement attendu de -std=c++0x:

D. 7 dit

Chaque en-tête C, dont chacun a un nom du nom du formulaire.h, se comporte comme si chaque nom dans la norme espace de noms de bibliothèque par le correspondant l'en-tête cname est placé dans le portée globale de l'espace de noms

OK, jusqu'à présent si facile. Que place <cstdint> dans l'espace de noms de bibliothèque standard?

18.4.1:

typedef unsigned integer type uint64_t; // optional

Comment optionnel? 18.4.1/2:

L'en-tête définit toutes les fonctions, types et macros identiques à 7.18 in la norme C

Drat. Que dit la norme C? Sortir n1256, 7.18.1.1 / 3:

Ces types sont facultatifs. Cependant, si une implémentation fournit un entier types avec des largeurs de 8, 16, 32, ou 64 peu, aucun peu de remplissage, et (pour le types signés) qui ont un deux de la représentation du complément, il doit définir le typedef correspondant noms

Mais accrochez-vous, sûrement sur Android avec -std=c++0x GCC fournit-il un type non signé 64 bits sans bits de remplissage: unsigned long long. Donc <cstdint> est tenu de fournir std::uint64_t, et donc stdint.h est tenu de fournir uint64_t dans l'espace de noms global.

Continuez, quelqu'un me dit Pourquoi je me trompe :-) une possibilité est que C++0x se réfère à "ISO/IEC 9899:1999 langages de programmation - C" sans spécifier de version. Peut-il vraiment être que (a) 7.18.1.1 / 3 a été ajouté dans l'un des TCs, et aussi (b) C++0x a l'intention de faire référence à la norme originale à partir de 1999, pas les amendements depuis lors? Je doute que l'un ou l'autre soit le cas, mais je n'ai pas le C99 original en main pour vérifier (A) et je ne suis même pas sûr de savoir comment vérifier (b).

Edit: oh, quant à laquelle devrait être utilisé -std=c++0x n'est pas encore vraiment un mode strict conforme aux normes, car il n'y a pas encore de norme stricte. Et même s'il y avait une norme, gcc 4.4.3 n'est certainement pas une implémentation terminée. Donc, je ne vois pas grand besoin de l'utiliser si -std=gnu++0x est en fait plus complet , au moins à cet égard pour votre combinaison de version et de plate-forme gcc.

Cependant, {[11] } activera d'autres extensions GNU, que vous ne voudrez peut-être pas utiliser votre code. Si vous visez à écrire portable C++0x, puis finalement vous voudriez passer à -std=c++0x. Mais je ne pense pas que GCC 4.4 ou toute autre implémentation en cours de C++0x soit assez complète pour qu'il soit pratique d'écrire du code à partir de la norme (brouillon), de sorte que vous pourriez dire avec un visage droit "je programmation C++0x, et ce n'est que 2011!". Donc, je dirais, utilisez celui qui fonctionne, et comprenez que celui que vous utilisez maintenant, vous passerez probablement à -std=c++11 finalement de toute façon.

20
répondu Steve Jessop 2011-02-27 23:29:42