10
votes

Quelle est la caractéristique la plus dangereuse de C ++?

J'ai entendu beaucoup de fois que la phrase de Bjarne Stroustrup "C ++ rend plus difficile de te tirer dans le pied; mais quand tu le fais, ça enlève toute la jambe" et je ne fais pas Je sais vraiment si c'est aussi terrible que cela sonne.

Quelle est la pire chose qui vous a jamais arrivée (ou plus correctement, votre logiciel) tout en programmant en C ++? De quelle manière peut-il être plus dangereux que dire la plaine C, par exemple?


3 commentaires

Chaque fois que vous le faites, vous le faites, il n'y a rien de dangereux. Le pistolet dans les mains de singe peut toujours conduire à des problèmes.


Ouais, mais la banane mène beaucoup moins.


Je ne vous donnerai pas de réponse, mais je vais vous dire le conseil le plus mémorable que j'ai jamais entendu sur le sujet. C'est-à-dire que "si vous oubliez d'attraper une exception, toute votre application quitte!". Pour une raison quelconque, cela me semblait assez inquiétant à cette époque.


11 Réponses :


1
votes

Sa mise en œuvre de la manipulation des exceptions est une inadapture facile pour les fuites de mémoire.


3 commentaires

Comment? Pensez-vous au cas des exceptions projetées par le pointeur au lieu de référence?


Avec le vrai Raii, ce n'est pas un problème, je pense


Être en désaccord. Je ne vois aucune raison de la mémoire à fuir avec des exceptions. La norme est très claire dans la manière dont l'exception est pulsée.



11
votes
delete array;

2 commentaires

Comme vous le savez probablement, pourquoi cela ne se produit pas avec MALLOC et libre est que cela ne fait pas de distinction entre un tableau ou un seul article.


Exactement. Donc, je me suis débarrassé de la clause "semble" là; J'étais prudent parce que ça fait si longtemps que j'ai utilisé c ...



7
votes

Les débordements de tampon doivent être les choses les plus dangereuses de C et C ++. C'est aussi la raison pour laquelle Microsoft annoncé qu'ils ont ajouté memcpy () à leur liste de fonctions interdites

Un autre héritage est un autre


1 commentaires

Chose la plus dangereuse de toute langue sans protection envahissante.



0
votes

Probablement l'aspect le plus dangereux de C ++ qui n'existe pas dans C est la possibilité de remplacer les opérateurs pour des types complexes. Il peut être très facile de faire une addition de soustraction (et inversement), par exemple.

C'est stupide que tout le monde est cela, mais cela peut être fait. Rendre dangereux.


0 commentaires

5
votes

L'exigence destructeurs virtuels est facile pour les nouveaux venus à manquer (bien que je pense que la plupart des compilateurs sont suffisamment intelligents pour pointer celui-ci).


2 commentaires

Quelle exigence destructeurs virtuels?


@Magnus: Si vous détruisez un objet via un pointeur sur sa base (ou n'importe quel ancêtres), alors si le destructeur n'est pas virtuel, le destructeur incorrect sera appelé. Ainsi, les classes conçues pour être remplacées devraient probablement avoir un destructeur virtuel.



2
votes

surcharge de l'opérateur . Très facile de rendre les choses difficiles à comprendre ce qui se passe. Il est facile de négliger le fait qu'une surcharge se passe, même pour les développeurs expérimentés C ++.


1 commentaires

Les opérateurs surchargés ont leur place. Je ne dirais pas que la fonctionnalité est intrinsèquement mauvaise - cela peut être assez utile. C'est quand les gens commencent à les définir à faire les choses contre-intuitivement que les difficultés émergent. Les opérateurs surchargés, lorsqu'ils sont utilisés correctement, peuvent rendre le code plus simple et plus propre.



0
votes

Si vous allez comparer la sécurité de C ++ versus c, vous avez raté le point de cette phrase. C ++ n'est sans doute pas plus sûr que c.

Où la comparaison peut vraiment être faite est d'une langue telle que Java. Essentiellement, Java gère votre mémoire pour vous, de sorte que vous ne vous retrouverez pas avec un comportement indéfini lors de l'appel de la mémoire en dehors de la mémoire que votre programme utilise actuellement (sortir des matrices, etc.).

Pour résoudre votre question, la pire chose qui m'est arrivée était un débordement de tampon pour remplacer mon propre mot de passe (je l'ai fait à dessein, cependant).


4 commentaires

Très vrai. Les aspects les plus dangereux de C ++ sont en réalité des portes de C. Il existe quelques fonctionnalités de C ++ qui n'existent pas dans C (comme surcharge de l'opérateur); Je crois que la question pose la question de ceux-ci.


En fait, la vérification du type statique peut être appliquée plus strictement en C ++ que dans C, je pense (les Typefs sont à la fin quelque chose comme "tout ce qui va")


C ++ vous donne le choix, vous pouvez utiliser des limites de tableau vérifiées si vous le souhaitez - mais vous n'avez pas à (et payez la peine de performance) si vous n'avez pas besoin de


C ++ est certainement plus sûr que c en ce sens qu'il vous donne les outils pour éviter les pièges tels que les accès à la mémoire des limites.



0
votes

Je me suis toujours demandé à propos de cette citation. Je ne peux penser à aucune façon dont C ++ est plus dangereux que C.

Dans tous les cas, je dois dire que la «fonctionnalité» la plus dangereuse est que rien ne vous empêche d'accéder à la mémoire non allouée. C'est une erreur presque impossible de déboguer, provoque toutes sortes de comportements aléatoires, des crashs à rien du tout à un comportement étrange.


0 commentaires

2
votes

J'ai passé cette à une fonction d'assistance dans un autre objet d'un constructeur. La fonction d'assistant a ajouté le pointeur sur une liste d'objets qu'il maintenait. Bien entendu, après la fin du constructeur et renvoyé, l'objet était situé dans un emplacement très différent en mémoire et le pointeur stocké dans l'autre objet n'était plus valide. Yikes!


6 commentaires

Il n'est jamais en sécurité pour fuir "ceci" d'un constructeur. Particulièrement non dans un environnement multi-fileté, auquel cas l'objet peut être partiellement construit ou partiellement visible. Les objets ne peuvent pas être supposés être entièrement construits qu'après le retour du constructeur (ceci est également vrai de Java et C #).


On dirait que vous avez eu un bug.


Le vrai passage d'un "ceci" d'un objet partiellement construit peut être dangereux, mais je n'ai jamais envisagé (ni croire actuellement) que l'objet sera déplacé pendant la construction. Cela aurait trop d'incidences sur les variables des membres qui ont déjà été construites (dans le cadre de la variation de l'adresse, les membres devraient être copiés construits sur de nouveaux emplacements [la copie d'octets simplement ne suffit pas en C ++]).


Je ne sais pas avec certitude que l'objet a été déplacé, seulement que le "Ce" pointeur a été renvoyé à un emplacement différent après le retour du constructeur. Le pointeur que j'ai passé et stocké a été renvoyé à une adresse mémoire très faible et après son retour du constructeur, "ceci" a été renvoyé à un endroit beaucoup plus ordinaire. Ceci du débogueur vs. En tout cas, il a échoué lorsque nous avons essayé d'appeler une méthode avec elle! Je peux explorer cela plus minutieusement .. à l'époque, nous avons juste levé nos sourcils, la corrigée et l'a déployée.


Avec un héritage multiple, l'adresse de «ceci» dépend de quelle classe vous êtes actuellement. Donc, peut-être que l'appel était implicitement lancé autour d'une hiérarchie et la conversion a utilisé une valeur cachée qui n'avait pas été initialisée?


@Nick - Cela ressemble à un problème potentiellement intéressant. Envisagez de la publier comme une question ici.



0
votes
  • Surcharge de l'opérateur si non implémenté correctement
  • Héritage multiple (facile à utiliser)
  • Overflow tampon

0 commentaires

2
votes

J'aurais dites la conversion de type automatique. C ++ peut créer des variables temporaires de manière non intuitive par la conversion automatique de type.


0 commentaires