Les modèles C ++ sont connus pour générer des messages d'erreur longs et illisibles. J'ai une idée générale de la raison pour laquelle les messages d'erreur de modèle en C ++ sont si mauvais. Essentiellement, le problème est que l'erreur n'est déclenchée que lorsque le compilateur rencontre une syntaxe qui n'est pas prise en charge par un certain type dans un modèle. Par exemple:
template <class T>
void dosomething(T& x) { x += 5; }
Si T
ne prend pas en charge l' +=
opérateur, le compilateur générera un message d'erreur. Et si cela se produit au fond d'une bibliothèque quelque part, le message d'erreur peut contenir des milliers de lignes.
Mais les modèles C ++ ne sont essentiellement qu'un mécanisme de typage de canard au moment de la compilation. Une erreur de modèle C ++ est conceptuellement très similaire à une erreur de type d'exécution qui peut se produire dans un langage dynamique comme Python. Par exemple, considérez le code Python suivant:
def dosomething(x):
x.foo()
Ici, s'il x
n'a pas de foo()
méthode, l'interpréteur Python lève une exception et affiche une trace de pile avec un message d'erreur assez clair indiquant le problème. Même si l'erreur n'est déclenchée que lorsque l'interpréteur est au fond d'une fonction de bibliothèque, le message d'erreur d'exécution n'est toujours pas aussi mauvais que le vomissement illisible craché par un compilateur C ++ typique. Alors pourquoi un compilateur C ++ ne peut-il pas être plus clair sur ce qui ne va pas? Pourquoi certains messages d'erreur du modèle C ++ font-ils littéralement défiler la fenêtre de ma console pendant plus de 5 secondes?
la source
clang++
wink wink).Réponses:
Les messages d'erreur de modèle peuvent être notoires, mais ne sont en aucun cas toujours longs et illisibles. Dans ce cas, l'intégralité du message d'erreur (de gcc) est:
Comme dans votre exemple Python, vous obtenez une «trace de pile» de points d'instanciation de modèle et un message d'erreur clair indiquant le problème.
Parfois, les messages d'erreur liés aux modèles peuvent être beaucoup plus longs, pour diverses raisons:
La principale différence avec Python est le système de type statique, ce qui conduit à la nécessité d'inclure les noms de type (parfois longs) dans le message d'erreur. Sans eux, il serait parfois très difficile de diagnostiquer pourquoi la résolution de surcharge a échoué. Avec eux, votre défi n'est plus de deviner où est le problème, mais de déchiffrer les hiéroglyphes qui vous indiquent où il se trouve.
De plus, la vérification au moment de l'exécution signifie que le programme s'arrêtera à la première erreur qu'il rencontre, affichant uniquement un seul message. Un compilateur peut afficher toutes les erreurs qu'il rencontre jusqu'à ce qu'il abandonne; au moins en C ++, il ne doit pas s'arrêter sur la première erreur du fichier, car cela peut être la conséquence d'une erreur ultérieure.
la source
Voici quelques-unes des raisons évidentes:
C'est loin d'être exhaustif, mais vous avez une idée générale. Même si ce n'est pas facile, la majeure partie peut être guérie. Depuis des années, je dis aux gens de se procurer une copie de Comeau C ++ pour une utilisation régulière; J'ai probablement économisé assez d'un message d'erreur une fois pour payer le compilateur. Maintenant, Clang arrive au même point (et c'est encore moins cher).
Je terminerai par une observation générale qui ressemble à une blague, mais qui ne l'est vraiment pas. La plupart du temps, vrai travail d'un compilateur honnêtement est de transformer le code source dans les messages d'erreur. Il est grand temps que les fournisseurs se concentrent un peu mieux sur ce travail - même si je reconnais ouvertement que lorsque j'ai écrit des compilateurs, j'avais une forte tendance à le traiter comme secondaire (au mieux) et dans certains cas, je l'ai presque ignoré complètement.
la source
La réponse est simple, car Python a été conçu pour fonctionner de cette façon, alors que la plupart des éléments associés aux modèles sont arrivés par accident. Il n'a jamais été destiné à devenir un système complet de Turing en soi, par exemple. Et si vous ne pouvez pas délibérément planifier et raisonner sur ce qui se passe lorsque votre système fonctionne , pourquoi devrait-on s'attendre à une planification minutieuse et réfléchie de ce qui se passe en cas de problème?
De plus, comme vous l'avez souligné, l'interpréteur Python peut vous faciliter la tâche en affichant une trace de pile car il interprète le code Python. Si un compilateur C ++ rencontre une erreur de modèle et vous donne une trace de pile, ce serait tout aussi inutile que "vomir le modèle", n'est-ce pas?
la source