Blog 5 min de lecture

Utiliser ou ne pas utiliser les exceptions C++ : le débat

Share this article
Utiliser ou ne pas utiliser les exceptions C++ : le débat

Il y a plus de 20 ans, la gestion des exceptions a été ajoutée au C++. Après de nombreuses années d'expérience des développeurs avec cette fonctionnalité, nous disposons désormais d'un retour précieux sur ses avantages et ses inconvénients.

Explorons les opinions de quelques figures éminentes de la communauté C++ pour voir ce qu'ils pensent de l'utilisation des exceptions.

I- Les experts C++

Herb Sutter, tiré de son article :

En résumé : préférez les exceptions aux codes d'erreur pour signaler les erreurs. N'utilisez des codes de statut (comme les codes de retour ou errno) pour les erreurs que lorsque les exceptions ne peuvent pas être employées (lorsque vous ne contrôlez pas tout le code appelant possible et que vous ne pouvez pas garantir qu'il sera écrit en C++ et compilé avec le même compilateur et des options de compilation compatibles pour que la gestion des exceptions fonctionne), ainsi que pour les situations qui ne sont pas des erreurs. Utilisez d'autres méthodes, comme un arrêt contrôlé ou non, lorsque la récupération n'est pas nécessaire ou est impossible.

Bjarne Stroustrup, tiré de sa page FAQ :

En quoi les exceptions peuvent-elles m'être utiles ? La réponse de base est la suivante : utiliser les exceptions pour la gestion des erreurs rend votre code plus simple, plus propre et moins susceptible de laisser passer des erreurs. Mais qu'est-ce qui ne va pas avec « le bon vieux errno et les instructions if » ? La réponse de base : avec ces outils, votre gestion des erreurs et votre code normal sont étroitement entremêlés. Votre code devient alors confus et il devient difficile de garantir que toutes les erreurs ont été traitées (pensez au « code spaghetti » ou à un « enchevêtrement de tests »).

Scott Meyers, tiré de son livre « Effective C++ » :

Il y a quarante ans, le code truffé de goto était considéré comme une pratique parfaitement acceptable. Aujourd'hui, nous nous efforçons d'écrire des flux de contrôle structurés. Il y a vingt ans, les données accessibles globalement étaient considérées comme une bonne pratique. Aujourd'hui, nous nous efforçons d'encapsuler les données. Il y a dix ans, écrire des fonctions sans se soucier de l'impact des exceptions était une bonne pratique. Aujourd'hui, nous nous efforçons d'écrire du code sûr vis-à-vis des exceptions.

Joel Spolsky, tiré de son article :

On m'a demandé pourquoi je n'aime pas programmer avec les exceptions. Que ce soit en Java ou en C++, ma règle est la suivante :

1 – Ne jamais lever moi-même d'exception. 2 – Toujours intercepter toute exception susceptible d'être levée par une bibliothèque que j'utilise, sur la même ligne que celle où elle est levée, et la traiter immédiatement.

Andrei Alexandrescu, tiré de son article

Écrire du code sûr vis-à-vis des exceptions est difficile

Plus loin dans le même article, il explique comment l'utilisation des exceptions peut être simplifiée grâce à l'idiome du scope guard :

ScopeGuard est une généralisation d'une implémentation typique de l'idiome C++ « l'acquisition d'une ressource est une initialisation » (RAII). La différence est que ScopeGuard se concentre uniquement sur la partie nettoyage — vous effectuez l'acquisition de la ressource, et ScopeGuard se charge de la libérer. (En fait, le nettoyage est sans doute la partie la plus importante de l'idiome.)

Jon Kalb, tiré de son site web

L'utilisation sûre des exceptions est un problème non trivial avec lequel l'industrie se débat depuis près de deux décennies. Si vous éprouvez des craintes, des incertitudes ou des doutes quant à la sûreté des exceptions, ou si vous souhaitez simplement découvrir les meilleures pratiques d'utilisation des exceptions en C++, cette session est faite pour vous. Nous commencerons par « Quel est le problème que nous cherchons à résoudre ? », nous évoquerons les alternatives, nous reconnaîtrons les difficultés liées à l'utilisation des exceptions et nous passerons en revue quelques tentatives bien intentionnées mais malavisées de sûreté. Je présenterai ensuite un ensemble de lignes directrices qui constituent la base d'une utilisation sûre des exceptions, ainsi que des techniques d'implémentation solides, y compris comment effectuer la transition depuis une base de code legacy non sûre vis-à-vis des exceptions.

II- Des projets réels

D'après le guide de style de Boost :

Quand faut-il utiliser les exceptions ?

La réponse simple est : « chaque fois que les caractéristiques sémantiques et de performance des exceptions sont appropriées. »

D'après le guide de style de Google

À première vue, les avantages des exceptions l'emportent sur leurs coûts, en particulier dans les nouveaux projets. En revanche, pour du code existant, l'introduction des exceptions a des répercussions sur tout le code dépendant. Si les exceptions peuvent se propager au-delà d'un nouveau projet, il devient également problématique d'intégrer ce nouveau projet dans du code existant sans exceptions. Comme la majeure partie du code C++ existant chez Google n'est pas préparée à gérer les exceptions, il est relativement difficile d'adopter du nouveau code qui en génère.

Clang

L'équipe Clang a décidé de ne pas utiliser les exceptions C++ ; voici une citation de leur standard de codage :

Dans le but de réduire la taille du code et de l'exécutable, LLVM n'utilise ni RTTI (par exemple dynamic_cast<>) ni les exceptions. Ces deux fonctionnalités du langage violent le principe général du C++ selon lequel « vous ne payez que ce que vous utilisez », provoquant un gonflement de l'exécutable même si les exceptions ne sont jamais utilisées dans la base de code, ou si RTTI n'est jamais utilisé pour une classe. C'est pourquoi nous les désactivons globalement dans le code.

En revanche, LibreOffice utilise les exceptions C++.

En examinant de nombreux projets C++ open source bien connus, aucune préférence claire ne se dégage : les deux approches sont largement utilisées.

III- La communauté C++

Si l'on regarde les forums, les articles et les discussions sur les réseaux sociaux, on peut identifier trois points de vue principaux au sein de la communauté C++ :

  • Les utiliser — c'est la meilleure façon de gérer les circonstances exceptionnelles.
  • Les utiliser, mais avec beaucoup de prudence — elles ont certains effets secondaires.
  • Ne jamais les utiliser.

En tant que développeur C++, je suis très perplexe. Faut-il les utiliser ou non ?

Tous ces experts C++ soulèvent un problème majeur : écrire du code sûr vis-à-vis des exceptions n'est pas trivial. On peut classer les développeurs C++ en quatre catégories :

Catégorie 1 : ceux qui utilisent les exceptions C++ sans se soucier de la sûreté des exceptions.

Catégorie 2 : ceux qui utilisent les exceptions C++ et sont conscients des problèmes de sûreté des exceptions.

Catégorie 3 : ceux qui ne les utilisent pas, mais ne comprennent pas pleinement les avantages et les inconvénients des exceptions.

Catégorie 4 : ceux qui ne les utilisent pas parce qu'ils en comprennent parfaitement les inconvénients.

Les développeurs des catégories 2 et 4 savent exactement ce qu'ils font. En revanche, ceux des catégories 1 et 3 ne comprennent pas pleinement le mécanisme des exceptions, ce qui peut affecter la qualité de leur code. Peut-être que débattre de l'opportunité d'utiliser les exceptions n'est pas la bonne question. Ce qui compte davantage, c'est de comprendre les avantages et les inconvénients de leur utilisation. C'est à vous de faire un choix en fonction de vos contraintes spécifiques. Personne ne peut vous en vouloir de choisir l'une ou l'autre des deux approches.

Share this article