27 votes

La suppression d'un pointeur null void* est-elle un comportement indéfini ?

Je sais que delete L'utilisation d'un pointeur nul n'est pas possible :

Dans les deux cas, si la valeur de l'opérande de delete est le pointeur nul, l'opération n'a aucun effet.
(norme C++ <code>5.3.5 [expr.delete] p2</code> )

Et aussi que la suppression d'un void* est un comportement indéfini car le destructeur ne peut pas être appelé puisqu'il n'y a pas d'objets de type void :

Dans la première alternative ( delete object ), la valeur de l'opérande de suppression sera un pointeur vers un objet autre qu'un tableau ou un pointeur vers un sous-objet représentant une classe de base d'un tel objet. Sinon, le comportement est indéfini.
(norme C++ <code>5.3.5 [expr.delete] p2</code> )

Normalement, je considère que les choses qui sont énumérées en premier l'emportent sur celles qui sont énumérées plus loin, mais qu'en est-il de la nullité ? void* comme les suivantes ?

void* p = 0;
delete p; // UB or well-defined?

10voto

AProgrammer Points 31212

Je me demande comment on peut arriver à une situation où l'on supprime un pointeur uniquement s'il est nul. Mais pour rester dans le domaine du droit des langues...

En C++ 03

5.3.5/1

l'opérande de suppression doit avoir un type de pointeur ou un type de classe ayant une conversion unique en type de pointeur.

void* est un type de pointeur, donc un pointeur void nul répond à l'exigence statique.

5.3.5/2

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

Et cela donne le comportement souhaité.

5.3.5/3

Dans la première alternative (suppression d'objet), si le type statique de l'opérande est différent de son type dynamique, le type statique doit être une classe de base du type dynamique de l'opérande et le type statique doit avoir un destructeur virtuel ou le comportement est indéfini.

Ce n'est pas pertinent, un pointeur nul ne référence pas un objet sur lequel vérifier la contrainte supplémentaire.

En C++ 0X

5.3.5/1

L'opérande doit avoir un pointeur vers un type d'objet, ou un type de classe ayant une seule fonction de conversion non explicite (12.3.2) vers un pointeur vers un type d'objet.

void* n'est pas un pointeur vers un type d'objet, il doit donc être rejeté.

8voto

Nawaz Points 148870

§5.3.5/3 dit,

Dans la première alternative (supprimer ), si le type statique de l'objet est différent de son type dynamique dynamique, le type statique doit être une classe de base classe du type dynamique de l'opérande et le type statique doit avoir un destructeur virtuel ou le comportement est indéfini. Dans la deuxième solution (supprimer un tableau), si le type dynamique de l'objet à supprimer diffère de son type statique, le comportement est indéfini 73

Dans la note de bas de page, il est dit,

73 - Cela implique qu'un objet ne peut pas être supprimé à l'aide d'un pointeur de type void* car il n'existe pas d'objets de type void.

Donc oui, c'est UB.

Maintenant, une fois qu'il entre dans la ville du comportement indéfini, il importe peu qu'il soit nul ou non, puisque son comportement ne peut pas rester bien défini précisément pour la raison qu'il déjà a obtenu une résidence dans la ville au comportement indéfini.


EDITAR:

Il y a un autre sujet qui cite également la même chose et dit que c'est UB :

Est-il possible de supprimer un pointeur void en toute sécurité ?

2voto

Prasoon Saurav Points 47488

Je crois que c'est un comportement non défini. new void n'est pas autorisé (vous n'êtes pas autorisé à créer des objets de type void ) donc appeler delete en un void* ne devrait pas non plus avoir de sens. Peu importe s'il pointe sur NULL ou pas. Je n'utiliserais jamais une telle chose dans mon code.

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