Je sais qu'au moins une des modifications de C ++ 11 qui entraînera l'arrêt de la compilation de l'ancien code: l'introduction de explicit operator bool()
dans la bibliothèque standard, remplaçant les anciennes instances de operator void*()
. Certes, le code que cela cassera est probablement un code qui n'aurait pas dû être valide en premier lieu, mais c'est quand même un changement de rupture: les programmes qui étaient valides ne le sont plus.
Y a-t-il d'autres changements de rupture?
export
mot-clé? Je vais me chercher un manteau.mystream.good()
n'est pas le même quebool(mystream)
?good()
est vrai si aucun indicateur n'est défini.bool(mystream)
est toujours faux si seulementeofbit
est défini.!mystream.fail()
serait l'équivalent correct.Réponses:
Le FDIS a une section pour les incompatibilités, en annexe
C.2
"C ++ et ISO C ++ 2003".Résumé, paraphrasant le FDIS ici, pour le rendre (mieux) approprié comme réponse SO. J'ai ajouté quelques exemples pour illustrer les différences.
Il y a quelques incompatibilités liées à la bibliothèque dont je ne connais pas exactement les implications, donc je laisse celles-ci aux autres pour les développer.
Langage de base
(certes pas vraiment un problème de compatibilité pour la plupart des gens).
Exemple par moi:
De telles astuces de sizeof ont été utilisées par certains SFINAE, et doivent être modifiées maintenant :)
Exemple par moi:
Ce code appelle
terminate
en C ++ 0x, mais pas en C ++ 03. Parce que la spécification d'exception implicite deA::~A
C ++ 0x estnoexcept(true)
.En C ++ 03,
>>
serait toujours le jeton de l'opérateur de décalage.Exemple par moi:
En C ++ 03, cela appelle
f(long)
, mais en C ++ 0x, cela appellef(int)
. Il convient de noter que dans C ++ 03 et C ++ 0x, les appels suivantsf(B)
(le contexte d'instanciation ne considère toujours que les déclarations de liaison externe).La meilleure correspondance
f(A)
n'est pas prise, car elle n'a pas de liaison externe.Modifications de la bibliothèque
la source
export
, alors je pense que les autres TU n'auraient pas besoin de s'appuyer sur l'instanciation explicite, mais pourraient instancier le modèle eux-mêmes. Ensuite, cela ferait une différence que les fonctions de liaison interne soient visibles ou non dans le contexte d'instanciation.La signification du mot clé auto a changé.
la source
auto
mot clé, quelque chose ne va pas avec votre code. Pourquoi diable l'utiliseriez-vous?auto
reste valide en C ++ 11.int main() { auto int i = 0; return i; }
est parfaitement valide en C ++ 03, mais une erreur de syntaxe en C ++ 11. Le seul avertissement que je peux obtenir des compilateurs pour le donner en mode C ++ 03 est un avertissement sur la compatibilité.Briser le changement?
Eh bien, pour une chose, si vous avez utilisé
decltype
,constexpr
,nullptr
, etc. comme identifiants alors vous pouvez être en difficulté ...la source
Certaines incompatibilités de base qui ne sont pas couvertes par la section des incompatibilités:
C ++ 0x traite le nom de classe injecté comme un modèle, si le nom est passé comme argument à un paramètre de modèle de modèle, et comme un type s'il est passé à un paramètre de type de modèle.
Un code C ++ 03 valide peut se comporter différemment s'il repose sur le nom de classe injecté pour être toujours un type dans ces scénarios. Exemple de code tiré de mon PR clang
En C ++ 03, le code appelle la seconde
g
fois.C ++ 0x fait que certains noms qui étaient dépendants en C ++ 03 sont désormais non dépendants. Et nécessite la recherche de noms pour les noms qualifiés non dépendants qui font référence aux membres du modèle de classe actuel à répéter lors de l'instanciation, et nécessite la vérification que ces noms recherchent de la même manière que dans le contexte de définition du modèle.
Le code C ++ 03 valide qui dépend de la règle de dominance peut désormais ne plus être compilé à cause de ce changement.
Exemple:
Ce code C ++ 03 valide qui appelle
A<int>::f
n'est pas valide en C ++ 0x, car la recherche de nom lors de l'instanciation trouvera,A<int>::f
par opposition àB::f
, provoquant un conflit avec la recherche at-definition.À ce stade, il n'est pas clair s'il s'agit d'un défaut du FDIS. Le comité en est conscient et évaluera la situation.
Une déclaration using où la dernière partie est identique à l'identificateur dans la dernière partie du qualificatif du nom qualifié désignant une classe de base, cette déclaration using nomme désormais le constructeur, au lieu des membres portant ce nom.
Exemple:
L'exemple de code ci-dessus est bien formé en C ++ 03, mais mal formé en C ++ 0x, car il
A::B
est toujours inaccessible enmain
.la source
L'échec d'extraction de flux est traité différemment.
Exemple
Modifier la proposition
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2011/n3246.html#23
Référence standard
Implémentations
GCC 4.8 sort correctement pour C ++ 11 :
GCC 4.5-4.8 toutes les sorties pour C ++ 03 ce qui semble être un bug:
Visual C ++ 2008 Express affiche correctement pour C ++ 03:
Visual C ++ 2012 Express affiche de manière incorrecte pour C ++ 11, ce qui semble être un problème de statut d'implémentation:
la source
En quoi l'introduction d'opérateurs de conversion explicites est-elle un changement de rupture? L'ancienne version sera toujours aussi "valide" qu'auparavant.Oui, le changement de
operator void*() const
àexplicit operator bool() const
sera un changement de rupture, mais seulement s'il est utilisé d'une manière qui est mauvaise en soi. Le code conforme ne sera pas rompu.Maintenant, un autre changement de rupture est l'interdiction de réduire les conversions lors de l'initialisation globale :
Edit : N'oubliez pas,
std::identity<T>
sera supprimé en C ++ 0x (voir la note). C'est une structure de commodité pour rendre les types dépendants. Étant donné que la structure ne fait vraiment pas grand-chose, cela devrait le corriger:la source
operator void*
.bool ok = cin >> a; cout << "done reading" << endl; if (ok) { ... }
Il n'y a vraiment rien de mal à cela en C ++ 03, pourtant c'est devenu une erreur en C ++ 11. (Remarque: GCC 4.9 est toujoursoperator void*() const
là, c'est pourquoi il accepte le code en mode C ++ 11.)std::identity<T>
n'a pas été supprimé en C ++ 11, car il ne faisait pas partie de C ++ 03. Il existait brièvement dans le projet de C ++ 11 et a été supprimé du projet avant la normalisation.Il y a de nombreuses modifications à la bibliothèque de conteneurs qui permettent un code plus efficace mais rompent silencieusement la compatibilité descendante pour quelques cas d'angle.
Considérez, par exemple, la
std::vector
construction par défaut, C ++ 0x et les modifications de rupture .la source
Il y a eu beaucoup de discussions sur les mouvements implicites brisant la compatibilité descendante
( une page plus ancienne avec une discussion pertinente )
Si vous lisez les commentaires, le retour de mouvement implicite est également un changement de rupture.
la source
C ++ 03: valide.
C ++ 0x:
error: parameter declared 'auto'
la source
struct x
et sans nom.Caractéristiques linguistiques
>>
Composants de bibliothèque standard
Fonctions obsolètes
la source