7
votes

C ++ Syntaxe d'opérateur de suppression du tableau C ++

Après que je faisais, disez

foo * array = nouveau foo [n];

Je l'ai toujours supprimé de cette façon

Supprimer [] tableau;

Cependant, parfois, je l'ai vu de cette façon:

Supprimer [N] tableau;

Comme il semble compiler et travailler (au moins dans MSVC2005), je me demande: Quelle est la bonne façon de le faire? Pourquoi cela compile-t-il dans l'autre sens, alors?


0 commentaires

7 Réponses :


5
votes

Supprimer [] tableau; est la forme correcte.


0 commentaires

4
votes

Le bon moyen est de faire Supprimer [] tableau; . Je ne savais même pas Supprimer [N] tableau; compilerait (et je doute que cela devrait).


3 commentaires

Il compile sur VC9 avec un avertissement C4208: Extension non standard utilisée: Supprimer [exp] - EXP évaluée mais ignorée Je ne fais pas ce que cela signifie


Cela signifie que le code est (1) non valide C ++ et (2) l'expression n est évalué mais ignoré. C'est assez non pertinent, mais cela décrit ce qui se passe si vous avez écrit le tableau Supprimer [N ++]; - N est d'abord incrémenté, puis ignoré.


Vraiment, il est d'abord ignoré puis incrémenté :)



5
votes

Si le second cas est correct ou non, je recommanderais d'utiliser en premier comme étant moins sujet aux erreurs.

Visual Studio compile beaucoup de choses que cela ne devrait pas.


1 commentaires

"Visual Studio compile beaucoup de choses que cela ne devrait pas." Amen.



10
votes

Supprimer [n] tableau n'est pas valide. Il n'est pas défini dans la norme C ++: Section 5.3.5 Définit une expression Supprimer comme Supprimer Expr ou Suppr [] Expr , et rien d'autre. Il ne compile pas sur GCC (version 4.1.2). Quant pourquoi il compile dans Visual C ++: Demandez à Microsoft.


2 commentaires

Quelle standard C ++? Et avez-vous un lien / refer, où on peut le trouver?


@Kissaki: J'aurais référé à C ++ 03, qui n'est pas légalement disponible en ligne. Cependant, le libellé est très similaire dans C ++ 11, dont un brouillon est disponible à Open-Std.org/jtc1/sc22/wg21/docs/papers/2011/n3242.pdf



13
votes

Vous pouvez vérifier ce lien MSDN: Supprimer [n] opérateur . La valeur est ignorée.

Modifier J'ai essayé ce code d'exemple sur VC9: xxx

sortie est: test !!

donc l'expression est évaluée mais la valeur de retour est ignorée. Je suis surpris de dire le moins que je ne peux pas penser à un scénario pourquoi cela est requis.


3 commentaires

Cela signifie-t-il que vous pouvez supprimer [2n] tableau; et cela compilerait


Merci, c'est ce que je cherchais.


Je suppose que cette syntaxe était valide dans un dialecte pré-standard de C ++, de sorte que le comportement "évaluer et ignorer" serait nécessaire pour un peu hypothétique de code antique qui dépend d'un effet secondaire de l'expression. Je suis plus surpris que le soutien de cette syntaxe soit activé par défaut dans n'importe quel compilateur moderne.



-2
votes

Si cela fonctionne, c'est une extension non standard.

delete array; 


5 commentaires

Le comportement de la deuxième forme (sans crochets) est clairement défini pour les pointeurs non-réseau. Son comportement pour les tableaux n'est pas. Quoi qu'il en soit, je suppose que c'est la raison pour laquelle quelqu'un vous a voté.


Supprimer le tableau ne "fonctionne pas" dans aucun sens du mot, sauf si vous voulez dire qu'il ne plante pas le programme. Il ne récupérera pas toute la mémoire allouée en premier lieu et si elle ne plante pas, elle n'exécutera que le destructeur sur le premier objet de la matrice. (Qui est également une erreur si vous avez fait nouveau foo [0] .)


@Bill: J'aimerais pouvoir voter - voter des commentaires. Votre déclaration pourrait être vraie parfois et à d'autres moments, cela pourrait ne pas. Voyez ici: Stackoverflow.com/Questtions/1553382/1553407#1553407#1553407 et mon commentaire ici: Stackoverflow.com/questions/1553382/1553391#1553391


@Bill: Supprimer le tableau; (Sans parenthèses) Supprimer tous les éléments sur Certaines implémentations (c'est quel moyen dépendant de la mise en œuvre) et, étant donné que l'exemple de la question concerne les types d'int, aucun destructeurs ne doit être appelé.


@sbi - Je pense que vous et moi avons différentes définitions pratiques du "travail", mais je vois votre point. @Nicholaz - Assez juste, je n'ai pas réalisé que certaines implémentations l'ont fait.



4
votes

Premier point: Il n'y a presque jamais de bonne raison d'utiliser la forme de la matrice de nouveau ou de Supprimer pour commencer - utilisez STD :: Vector (ou un autre conteneur) à la place.

seconde: retour dans les âges sombres de C ++, vous deviez spécifier la taille de la matrice que vous supprimez, de sorte que si vous utilisiez x = nouveau t [n] , la suppression correspondante était < Code> Supprimer [N] x . L'obligation de spécifier explicitement la taille a été supprimée il y a longtemps , mais certains compilateurs (en particulier ceux qui se soucient de la compatibilité en retard avec le code antique) le permettent toujours de cela.

sauf si vous avez vraiment besoin de rester compatible avec un compilateur ancien (un de 20 ans ou plus), vous ne devriez pas l'utiliser. Encore une fois, sauf si vous devez rester compatible avec un compilateur si vieux, il ne prend pas en charge aucun conteneur standard, vous ne devez pas utiliser la forme de réseau de nouvelles ou supprimées en premier lieu. Il suffit d'arrêter!


3 commentaires

Merci pour le cours d'histoire. Ensuite, si je devais passer une gamme dynamique de, disons, flotte, à une bibliothèque tiers, ce qui serait la bonne façon de le faire avec des conteneurs standard?


Utilisez un vecteur. Lorsque vous devez passer l'adresse / la longueur, utilisez et VEC [0] et Vec.Size ().


+1: Dans le projet SEP '94 de la norme, la syntaxe était déjà 'Supprimer []'. Et la même année, la conception et l'évolution (P218) avaient le commentaire que cette syntaxe "... s'est révélée trop sujette d'erreur, de sorte que le fardeau de garder la trace du nombre d'éléments ait été placé sur la mise en œuvre."