Las plantillas de C ++ son conocidas por generar mensajes de error largos e ilegibles. Tengo una idea general de por qué los mensajes de error de plantilla en C ++ son tan malos. Esencialmente, el problema es que el error no se activa hasta que el compilador encuentra una sintaxis que no es compatible con cierto tipo en una plantilla. Por ejemplo:
template <class T>
void dosomething(T& x) { x += 5; }
Si T
no es compatible con el +=
operador, el compilador generará un mensaje de error. Y si esto sucede en lo profundo de una biblioteca en algún lugar, el mensaje de error puede tener miles de líneas de largo.
Pero las plantillas C ++ son esencialmente solo un mecanismo para escribir en tiempo de compilación. Un error de plantilla de C ++ es conceptualmente muy similar a un error de tipo de tiempo de ejecución que puede ocurrir en un lenguaje dinámico como Python. Por ejemplo, considere el siguiente código de Python:
def dosomething(x):
x.foo()
Aquí, si x
no tiene un foo()
método, el intérprete de Python lanza una excepción y muestra un seguimiento de la pila junto con un mensaje de error bastante claro que indica el problema. Incluso si el error no se activa hasta que el intérprete se encuentre dentro de alguna función de la biblioteca, el mensaje de error en tiempo de ejecución aún no es tan malo como el vómito ilegible arrojado por un compilador típico de C ++. Entonces, ¿por qué un compilador de C ++ no puede ser más claro sobre lo que salió mal? ¿Por qué algunos mensajes de error de plantilla C ++ literalmente hacen que la ventana de mi consola se desplace durante más de 5 segundos?
fuente
clang++
guiño guiño).Respuestas:
Los mensajes de error de la plantilla pueden ser notorios, pero de ninguna manera son siempre largos e ilegibles. En este caso, el mensaje de error completo (de gcc) es:
Como en su ejemplo de Python, obtiene un "seguimiento de pila" de puntos de creación de instancias de plantilla y un mensaje de error claro que indica el problema.
A veces, los mensajes de error relacionados con la plantilla pueden ser mucho más largos, por varias razones:
La principal diferencia con Python es el sistema de tipo estático, lo que lleva a la necesidad de incluir los nombres de tipo (a veces largos) en el mensaje de error. Sin ellos, a veces sería muy difícil diagnosticar por qué falló la resolución de sobrecarga. Con ellos, tu desafío ya no es adivinar dónde está el problema, sino descifrar los jeroglíficos que te dicen dónde está.
Además, la comprobación en tiempo de ejecución significa que el programa se detendrá en el primer error que encuentre, mostrando solo un mensaje. Un compilador puede mostrar todos los errores que encuentra, hasta que se da por vencido; al menos en C ++, no debería detenerse en el primer error en el archivo, ya que puede ser consecuencia de un error posterior.
fuente
Algunas de las razones obvias incluyen:
Eso está lejos de ser exhaustivo, pero se entiende la idea general. Incluso si no es fácil, la mayor parte se puede curar. Durante años, le he estado diciendo a la gente que obtenga una copia de Comeau C ++ para uso regular; Probablemente he guardado lo suficiente de un mensaje de error una vez para pagar el compilador. Ahora Clang está llegando al mismo punto (y es aún menos costoso).
Terminaré con una observación general que suena como una broma, pero realmente no lo es. La mayoría de las veces, el verdadero trabajo de un compilador honestamente es convertir el código fuente en mensajes de error. Ya es hora de que los proveedores se concentren en hacer ese trabajo un poco mejor, aunque admitiré abiertamente que cuando escribí compiladores, tuve una fuerte tendencia a tratarlo como secundario (en el mejor de los casos) y en algunos casos casi lo ignoré completamente.
fuente
La respuesta simple es, porque Python fue diseñado para funcionar de esa manera, mientras que muchas de las cosas asociadas con las plantillas surgieron por accidente. Nunca tuvo la intención de convertirse en un sistema completo de Turing en sí mismo, por ejemplo. Y si no puede planificar y razonar deliberadamente sobre lo que sucede cuando su sistema funciona , ¿por qué alguien debería esperar una planificación cuidadosa y reflexiva sobre lo que sucede cuando algo sale mal?
Además, como señaló, el intérprete de Python puede hacer que sea mucho más fácil para usted al mostrar un seguimiento de pila porque está interpretando el código de Python. Si un compilador de C ++ detecta un error de plantilla y le da un seguimiento de la pila, eso sería tan inútil como "vomitar plantilla", ¿no?
fuente