Introduction
Avec le C++ 14 (c'est-à-dire C++ 1y) Standard dans un état proche d'être définitif, les programmeurs doivent s'interroger sur la compatibilité ascendante, et questions liées à ces.
La question
Dans les réponses de cette question , il est indiqué que la norme comporte un annexe dédié aux informations concernant les modifications entre révisions.
Il serait utile d’expliquer ces problèmes potentiels dans le Annexe mentionné précédemment, peut-être à l’aide de documents officiels se rapportant à ce qui est mentionné ici.
Remarque : Dans cet article, je considère un "changement de changement" comme étant l'un des, ou les deux,;
1. un changement qui rendra légal C++ 11 mal formé lorsque compilé en tant que C++ 14, et;
2. une modification qui modifiera le comportement de l'exécution à la compilation C++ 14, vs C++ 11.
Le projet de norme ( n3797 ) comporte une section dédiée à ce type d’informations, dans laquelle elle décrit les différences (potentiellement décisives) entre une révision de la norme et une autre.
Ce message a utilisé cette section, [diff.cpp11]
, en tant que base d’une discussion semi-élaborée sur les modifications susceptibles d’affecter le code écrit pour C++ 11, mais compilé sous la forme C++ 14.
Le séparateur de chiffres a été introduit afin que l’on puisse, d’une manière plus lisible, écrire des littéraux numériques et les séparer de 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 le fragment de code ci-dessus, alors que les deux initialiseurs ont la même valeur.
Le problème potentiel concernant cette fonctionnalité est que single-quote désignait toujours le début/la fin d'un caractère-littéral dans C++ 11, mais dans C++ 14 un single-quote peut entourer un caractère-littéral, ou être utilisé de la manière indiquée précédemment (2).
Exemple d’extrait de code, légal à la fois C++ 11 et 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 }`
(Remarque: vous trouverez plus d'informations sur single-quotes sous forme de séparateurs de chiffres dans n3781.pdf )
C++ 14 introduit la possibilité de déclarer une surcharge globale de operator delete
approprié pour taille de localisation, ce qui n’était pas possible dans C++ 11.
Toutefois, la norme stipule également qu'un développeur ne peut déclarer qu'une seule des fonctions liées ci-dessous. Il doit déclarer soit aucune , soit les deux ; qui est indiqué dans [new.delete.single] p11.
void operator delete (void*) noexcept;
void operator delete (void*, std::size_t) noexcept; // sized deallocation
Informations supplémentaires sur le problème potentiel:
Les programmes existants qui redéfinissent la version globale non dimensionnée ne définissent pas également la version dimensionnée. Lorsqu'une implémentation introduit une version dimensionnée, le remplacement est incomplet et il est probable que les programmes appellent le désallocateur dimensionné fourni par l'implémentation sur les objets alloués avec l'allocateur fourni par le programmeur.
Remarque : Citation extraite de n3536 - Dislocation au format C++
(Remarque: Plus d’intérêt est disponible dans l’article intitulé n3536 - Dislocation au format C++ , écrit par Lawrence Crowl)
constexpr
fonctions-membres, plus implicitement const
Il y a beaucoup de changements dans constexpr en C++ 14, mais c'est le seul changement qui changera la sémantique entre C++ 11 et C++ 14 est la constante d'un fonction-membre marquée comme constexpr.
La raison derrière ce changement est de permettre à constexprfonctions-membres de muter l'objet auquel ils appartiennent, ce qui est autorisé en raison de la relaxation de - constexpr .
struct A { constexpr int func (); };
// struct A { constexpr int func () const; }; <-- C++11
// struct A { constexpr int func (); }; <-- C++14
Matériau recommandé pour ce changement et pourquoi il est suffisamment important pour introduire un risque de casse de code:
Exemple d’extrait de code, légal à la fois C++ 11 et 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
std::gets
std::gets
a été supprimé de la bibliothèque standard car considéré comme dangereux .
Les implications de ceci sont bien sûr qu'essayer de compiler le code écrit pour C++ 11, en C++ 14, où une telle fonction est utilisée, échouera probablement à la compilation.
(Remarque: il existe des façons d'écrire code qui ne manque pas de compiler et qui a un comportement différent, cela dépend de la suppression de std::gets
de la Bibliothèque standard)