71 votes

La règle de non-exception du guide de style C++ de Google ; STL ?

Le site de Google Guide de style C++ dit "Nous n'utilisons pas les exceptions". Le style ne mentionne pas la STL en ce qui concerne l'utilisation des exceptions. Puisque les allocateurs STL peuvent échouer, comment gèrent-ils les exceptions lancées par les conteneurs ?

  1. S'ils utilisent la STL, comment l'appelant est-il informé des échecs d'allocation ? Les méthodes STL comme push_back() ou carte operator[] ne renvoient aucun code d'état.
  2. S'ils n'utilisent pas la STL, quelle implémentation de conteneur utilisent-ils ?

8 votes

Avant que j'arrive et que je crie jusqu'à ce que j'obtienne ce que je veux, le magasin où je travaille avait la même convention stupide. Nous avons juste ignoré la réalité. Mon Pariez sur c'est que c'est aussi ce que fait Google.

1 votes

Peu de méthodes de la STL lèvent des exceptions...

15 votes

Google a des normes assez archaïques. Je suppose qu'ils engagent beaucoup d'étudiants et ne peuvent se permettre qu'un petit nombre de magiciens du C++.

58voto

Bo Persson Points 42821

Ils disent que ils n'utilisent pas d'exceptions, non pas que personne ne devrait les utiliser. Si vous regardez la justification, ils écrivent aussi :

Comme la plupart du code C++ existant chez Google n'est pas préparé à traiter les exceptions, il est comparativement difficile d'adopter un nouveau code qui génère des exceptions.

Le problème habituel de l'héritage :-(

4 votes

Et la question est de savoir comment ils gérer les conséquences de cette décision pour les interfaces des conteneurs STL, et non la façon dont les autres le font ;-)

4 votes

Ce n'est pas seulement un problème d'héritage. L'écriture de code sécurisé par les exceptions n'est pas triviale et il n'existe aucun outil (à ma connaissance) qui aide les développeurs dans ce domaine également. Ainsi, même les nouveaux codes sont sujets aux dangers des exceptions.

2 votes

La question n'est pas "leur décision est-elle raisonnable, ou tout le monde devrait-il suivre leur décision". Non, non et non. La question est de savoir s'il est possible d'utiliser des conteneurs stl et de respecter cette règle.

48voto

hoffmanj Points 311

Nous avons simplement Ne le fais pas. gérer les exceptions lancées par les conteneurs, au moins dans le code au niveau de l'application.

Je suis ingénieur chez Google Search et je travaille en C++ depuis 2008. Nous utilisons souvent les conteneurs STL. Je ne me souviens pas personnellement d'une seule défaillance ou d'un seul bogue majeur qui soit remonté jusqu'à quelque chose comme vector::push_back() ou map::operator[], où nous avons dit "oh mec, nous devons réécrire ce code parce que l'allocation pourrait échouer" ou "dang, si seulement nous utilisions des exceptions, cela aurait pu être évité". Un processus peut-il manquer de mémoire ? Oui, mais il s'agit généralement d'une simple erreur (par exemple, quelqu'un a ajouté un nouveau fichier de données volumineux au programme et a oublié d'augmenter l'allocation de RAM) ou d'une défaillance catastrophique pour laquelle il n'y a aucun moyen de récupérer et de continuer. Notre système gère et redémarre déjà les tâches automatiquement pour être robuste face à des machines avec des disques défectueux, des rayons cosmiques, etc. et ce n'est pas vraiment différent.

Donc, pour autant que je puisse dire, il n'y a pas de problème ici.

2 votes

@Hinata Hyuga : Merci pour les suggestions, mais je suis d'accord avec Loki Astari ; ma réponse repose entièrement sur mon expérience personnelle chez Google, ce qui, je pense, est une source valable pour répondre à une question Stack Overflow. J'ai toutefois tenu compte de certaines de vos suggestions en matière de grammaire. Merci à tous les deux !

0 votes

Comme je l'ai dit dans ma réponse ci-dessous, il est assez peu probable que vous voyiez des exceptions d'allocateur sur les systèmes modernes lorsque vous utilisez l'allocateur standard. Vous pourriez éventuellement utiliser un allocateur personnalisé, mais sinon, cela ne vaut pas la peine de s'en préoccuper.

2 votes

@hoffmanj J'ai vu du code utilisant des flux où le flux sous-jacent entrait dans un état d'échec et le code échouait silencieusement. Vérifier l'état du flux après chaque insertion (ala WinAPI) serait odieux. Il est vrai que le guide de style interdit l'utilisation de flux à des fins autres que la journalisation (en passant, cela inclut-il stringstream ?). Je suppose que ma question est, si vous interagissez avec une construction STL qui n'a pas une grande interface pour les conditions d'erreur autres que les exceptions, les interdisez-vous tout simplement ?

11voto

Mark Loeser Points 4007

Je suis presque sûr qu'ils veulent dire qu'ils n'utilisent pas les exceptions dans leur code. Si vous consultez leur cpplint script mais il vérifie que vous incluez les bons en-têtes pour les conteneurs STL (comme vector, list, etc.).

1 votes

Homm, est-ce qu'ils enveloppent chaque appel à la méthode stl dans catch(...) ?

3 votes

Mark, si vous voulez dire "ils ne lèvent pas d'exceptions dans leur code, mais ils permettent au code qu'ils appellent de lever des exceptions", cette interprétation est fausse. Cliquez sur le petit triangle à gauche de la règle. À partir des explications, il devient clair qu'ils ne veulent pas que des exceptions soient lancées à partir du code sous-jacent, également.

4 votes

Comme indiqué dans la section "Exceptions aux règles" "Vous pouvez vous écarter des règles lorsque vous traitez du code qui n'est pas conforme à ce guide de style", la STL n'a certainement pas été conçue en tenant compte des conventions Google.

7voto

Yongwei Wu Points 873

J'ai trouvé que Google le mentionne explicitement à propos de STL et des exceptions (c'est moi qui souligne) :

Bien que vous ne devriez pas utiliser les exceptions dans votre propre code, elles sont utilisées dans l'ATL et certaines STL, y compris celle fournie avec Visual C++. avec Visual C++. Lorsque vous utilisez l'ATL, vous devez définir _ATL_NO_EXCEPTIONS pour désactiver les exceptions. Vous devriez examiner si vous pouvez également désactiver les exceptions dans votre STL. d'activer les exceptions dans le compilateur. (Notez que ceci est seulement pour pour que la STL compile. Vous ne devez toujours pas écrire le code de gestion des exceptions d'exception vous-même. )

Je n'aime pas ces décisions (heureusement que je ne travaille pas pour Google), mais ils sont très clairs sur leur comportement et leurs intentions.

7voto

alastair Points 3040

De toute façon, les systèmes d'exploitation modernes ne peuvent pas gérer les échecs d'allocation ; pour optimiser les performances, ils surengagent généralement la mémoire. Par exemple, si vous appelez malloc() et demander un gros morceau de mémoire sous Linux, il réussira. même si la mémoire nécessaire pour la sauvegarder n'est pas présente. . Ce n'est que lorsque vous y accédez que le noyau tente réellement d'allouer des pages pour le sauvegarder, et à ce moment-là, il est trop tard pour vous dire que l'allocation a échoué de toute façon.

Donc :

  1. Sauf dans des cas particuliers, ne vous inquiétez pas des échecs d'allocation. Si la machine manque de mémoire, c'est un échec catastrophique dont vous ne pouvez pas vous remettre de manière fiable.

  2. Néanmoins, il est bon d'attraper les exceptions non gérées et de consigner les informations suivantes e.what() sortie, puis re- throw car cela peut être plus informatif qu'un backtrace, et les implémentations typiques des bibliothèques C++ ne le font pas automatiquement pour vous.

  3. L'énorme fil de discussion ci-dessus sur le fait que vous ne pouvez pas compter sur un plantage lorsque vous n'avez plus de mémoire est complètement absurde. La norme C(++) ne le garantit peut-être pas, mais sur les systèmes modernes, le plantage est le uniquement une chose sur laquelle vous pouvez compter si vous manquez de mémoire. . En particulier, vous ne pouvez pas compter sur l'obtention d'une NULL ou toute autre indication de votre allocateur, jusqu'à et y compris une exception C++.

  4. Si vous vous trouvez sur un système embarqué où la page zéro est accessible, je vous suggère fortement d'y remédier en mappant une page inaccessible à cet endroit. On ne peut pas compter sur les êtres humains pour vérifier si NULL des pointeurs partout, mais vous pouvez corriger cela en mappant une page une fois plutôt que d'essayer de corriger tous les problèmes possibles (passés, présents, etc.). et futur) où quelqu'un aurait pu manquer une NULL .

Je vais nuancer ce qui précède en disant qu'il est possible que vous utilisiez une sorte d'allocateur personnalisé, ou que vous soyez sur un système qui ne fait pas de sur-engagement (les systèmes embarqués sans swap en sont un exemple, mais pas le seul). Dans ce cas, peut-être que vous peut gérer les conditions d'absence de mémoire avec élégance, sur votre système . Mais en général, au XXIe siècle, j'ai bien peur que vous n'en ayez pas l'occasion ; la première fois que vous saurez que votre système n'a plus de mémoire, c'est lorsque les choses commenceront à planter.

1 votes

(1) La machine exécutant l'OOM est différente du processus exécutant l'OOM, du moins pour la (majorité) des processus qui sont encore en 32 bits : en raison de la fragmentation de l'espace d'adressage, vous commencerez à rencontrer des échecs d'allocation pour les grands blocs plus tôt que tard. (Comme nous en faisons l'expérience à plusieurs reprises sous Windows).

1 votes

(2) Si vous voulez planter (c.-à-d. vidanger le noyau) le processus pour les exceptions non gérées et analyser plus tard le vidage de plantage, il peut être préférable de pas attraper l'exception (et la relancer) car le fait de les attraper va dérouler la pile, ce qui conduira à plus d'erreurs ou au moins à obscurcir le vidage de la pile.

1 votes

Et, corrigez-moi, la dernière fois que j'ai vérifié, Windows ne s'engageait pas trop. Cela laisse donc une grande partie de la base d'installation à prendre en compte, n'est-ce pas ?

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