web-dev-qa-db-fra.com

Est-il toujours sûr de supprimer nullptr en c ++ 0x?

Dans c++03 il est assez clair que la suppression d'un pointeur nul n'a aucun effet. En effet, il est explicitement indiqué dans §5.3.5/2 cette:

Dans les deux cas, si la valeur de l'opérande de suppression est le pointeur nul, l'opération n'a aucun effet.

Cependant, dans l'actuel draft for c++0x cette phrase semble manquer. Dans le reste du brouillon, je n'ai pu trouver des phrases indiquant ce qui se passe que si l'opérande de delete-expression n'est pas la constante du pointeur nul. Supprime le pointeur nul toujours défini dans c++0x, et si oui, où?

Remarques:

Il existe des preuves circonstancielles significatives suggérant qu'il est toujours bien défini.

Tout d'abord, il y a les deux phrases dans §5.3.5/2 indiquant que

Dans la première alternative (objet delete), la valeur de l'opérande de delete peut être une valeur de pointeur nulle, ...

et

Dans la deuxième alternative (tableau de suppression), la valeur de l'opérande de suppression peut être une valeur de pointeur nulle ou ...

Ceux-ci disent que l'opérande est autorisé à être nul, mais ne définissent pas à eux seuls ce qui se passe s'il l'est.

Deuxièmement, changer le sens de delete 0 est un changement majeur et il est très peu probable que le comité des normes apporte ce changement particulier. En outre, il n'est pas fait mention d'un changement radical dans l'annexe de compatibilité (annexe C) du c++0x Brouillon. L'annexe C est cependant une section informative, donc cela n'a aucune incidence sur l'interprétation de la norme.

D'un autre côté, le fait que la suppression du pointeur nul soit requis pour n'avoir aucun effet implique une vérification supplémentaire de l'exécution. Dans beaucoup de code, l'opérande ne peut jamais être nul, donc cette vérification d'exécution est en conflit avec le principe de surcharge zéro. Peut-être que le comité a juste décidé de changer le comportement pour rendre le c ++ standard plus conforme aux objectifs de conception déclarés du langage.

69
Mankarse

5.3.5/7 dit:

Si la valeur de l'opérande de la suppression-expression n'est pas une valeur de pointeur nulle, la suppression-expression appellera une fonction de désallocation (3.7.4.2). Sinon, il n'est pas précisé si la fonction de désallocation sera appelée.

Et 3.7.4.2/3 dit:

La valeur du premier argument fourni à une fonction de désallocation peut être une valeur de pointeur nulle; si c'est le cas, et si la fonction de désallocation est fournie dans la bibliothèque standard, l'appel n'a aucun effet.

Le comportement est donc bien défini, tant que la fonction de désallocation standard est utilisée ou qu'une fonction de désallocation fournie par l'utilisateur gère correctement les pointeurs nuls.

86
interjay

D'un autre côté, le fait que la suppression du pointeur nul soit requis pour n'avoir aucun effet implique une vérification supplémentaire au moment de l'exécution.

Le nouveau libellé ne supprime pas cette vérification d'exécution pour un pointeur nul. Dans l'autre sens: le projet de norme est encore plus proche de dire qu'une implémentation doit faire un test de pointeur nul pour être conforme.

À noter également: l'ancienne norme se contredisait en ce qu'elle disait (5.3.5/2) que "si la valeur de l'opérande de suppression est le pointeur nul, l'opération n'a aucun effet", mais a déclaré plus tard que (5.3.5/7) l'expression "delete-expression appellera une fonction de désallocation". L'appel d'une fonction est un effet. Cela est d'autant plus vrai que la fonction qui est appelée pourrait bien être un operator delete Surchargé.

Le nouveau libellé supprime cette contradiction, laissant explicitement à l'implémentation le soin d'appeler la fonction de désallocation dans le cas de la suppression d'un pointeur nul.

6
David Hammen