58 votes

Quels sont les changements introduits dans C++14 qui peuvent potentiellement casser un programme écrit en C++11 ?

Introduction

Avec le C++14 (alias. C++1y ) Standard dans un état proche de la version finale, les programmeurs doivent se poser la question de la rétrocompatibilité et des problèmes qui y sont liés.


La question

Dans les réponses de cette question il est indiqué que la norme a un Annexe consacré aux informations concernant les changements entre les révisions.

Il serait utile que ces questions potentielles dans le cadre de l'initiative de l'UE sur l'égalité des sexes et l'autonomisation des femmes soient examinées. Annexe pourrait être expliqué, peut-être à l'aide de tout document officiel lié à ce qui est mentionné ici.

  • Selon la norme : Quels sont les changements introduits dans C++14 peuvent potentiellement casser un programme écrit en C++11 ?

231voto

Filip Roséen - refp Points 24995

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 )

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X