Nota : Dans ce billet, je considère un " changement brutal " d'être l'un ou l'autre, ou les deux ;
1. un changement qui rendra légal C++11 mal formé lorsqu'il est compilé en tant que C++14 et ;
2. une modification qui changera le comportement de l'exécution lorsqu'elle sera compilée en tant que C++14 , vs C++11 .
C++11 vs C++14 Que dit la norme ?
Le projet de norme ( n3797 ) a une section dédiée à ce type d'information, où sont décrites les différences (potentiellement cassantes) entre une révision de la norme et une autre.
Ce poste a utilisé cette section, [diff.cpp11]
comme base d'une discussion semi-élaborée sur les changements qui pourraient affecter le code écrit pour le système de gestion de l'information de l'UE. C++11 mais compilé comme C++14 .
C.3.1] Séparateurs de chiffres
Le séparateur de chiffres a été introduit pour que l'on puisse, d'une manière plus lisible, écrire des littéraux numériques et les diviser d'une manière plus naturelle.
int x = 10000000; // (1)
int y = 10'000'000; // (2), C++14
Il est facile de voir que (2) est beaucoup plus facile à lire que (1) dans l'extrait ci-dessus, alors que les deux initialisateurs ont la même valeur.
Le problème potentiel de cette fonctionnalité est que le guillemets simples a toujours indiqué le début/la fin d'une caractère-littéral en C++11 mais en C++14 a guillemets simples peut soit entourer un caractère-littéral ou utilisé de la manière indiquée précédemment (2) .
Exemple d'extrait, légal dans les deux cas C++11 y C++14 mais avec un comportement différent.
#define M(x, ...) __VA_ARGS__
int a[] = { M(1'2, 3'4, 5) };
// int a[] = { 5 }; <-- C++11
// int a[] = { 3'4, 5 }; <-- C++14
// ^-- semantically equivalent to `{ 34, 5 }`
( Note : Plus d'informations concernant guillemets simples comme séparateurs de chiffres peuvent être trouvés dans n3781.pdf )
C.3.2] Désallocation de taille
C++14 introduit l'opportunité de déclarer une surcharge globale de operator delete
adapté à désaffectation de taille ce qui n'était pas possible en C++11 .
Toutefois, la norme stipule également qu'un développeur ne peut pas déclarer une seule des deux fonctions connexes ci-dessous, il doit déclarer soit aucun ou les deux ce qui est indiqué dans [nouveau.supprimer.simple]p11 .
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
Informations supplémentaires concernant le problème potentiel :
Les programmes existants qui redéfinissent la version globale non dimensionnée ne définissent pas également définissent pas également la version dimensionnée. Lorsqu'une implémentation introduit une version le remplacement serait incomplet et il est probable que les programmes les programmes appelleraient le désalloueur de taille fournie par l'implémentation sur objets alloués avec l'allocateur fourni par le programmeur.
Nota : Citation tirée de n3536 - Déallocation à la taille C structurée (C++)
( Note : D'autres informations intéressantes sont disponibles dans le document intitulé n3536 - Déallocation à la taille C³³³³³³ écrit par Lawrence Crowl )
C.3.3] constexpr
les fonctions-membres, ne sont plus implicitement const
Il y a de nombreux changements à constexpr en C++14, mais le seul changement qui changera la sémantique entre C++11 y C++14 est le constance d'un fonction-membre marqué comme constexpr .
La raison d'être de ce changement est de permettre constexpr fonctions-membres de muter l'objet auquel ils appartiennent, ce qui est autorisé par la directive détente de constexpr .
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
Matériel recommandé sur ce changement, et pourquoi il est suffisamment important pour introduire une rupture de code potentielle :
Exemple d'extrait, légal dans les deux cas C++11 y C++14 mais avec un comportement différent
struct Obj {
constexpr int func (int) {
return 1;
}
constexpr int func (float) const {
return 2;
}
};
Obj const a = {};
int const x = a.func (123);
// int const x = 1; <-- C++11
// int const x = 2; <-- C++14
C.3.4] Suppression de std::gets
std::gets
a été supprimé de la bibliothèque standard parce qu'elle est considéré comme dangereux .
L'implication de ceci est bien sûr qu'essayer de compiler du code écrit pour C++11, en C++14, où une telle fonction est utilisée, échouera très probablement à compiler.
( Note : il existe des façons d'écrire code qui n'échoue pas à compiler, et qui a un comportement différent, qui dépend de la suppression de std::gets
de la Bibliothèque standard )