Programador (es) novato frustrado por la falta de un glosario de errores del compilador

65

Un amigo de mi familia me pidió un poco de ayuda mientras aprendía a programar (en lenguaje C). Mientras hablábamos, expresó su frustración por tener dificultades para entender los mensajes de error que su compilador (GCC) le está dando cuando comete errores. Él no entiende todos los términos utilizados, y algunas veces es su combinación lo que está más allá de su comprensión. Me preguntó: "¿Por qué la documentación del compilador no incluye explicaciones más largas de los mensajes de error?" - Y no tuve una buena respuesta para él.

Yo mismo, como programador con más experiencia, rara vez me encuentro en esta situación, pero ocurren esos casos raros, un mensaje de error exótico que no había encontrado antes. Me las arreglé para arreglármelas buscando el mensaje de error en un motor de búsqueda, pero aparentemente eso no siempre funciona para él, especialmente porque los errores que encuentra son más comunes y ocurren en múltiples casos distintos, lo que le cuesta relacionarse con su propio.

Entonces, ¿cómo debería un programador novato abordar el desafío de comprender los mensajes de error del compilador? Específicamente, con la combinación de C y GCC?

    
pregunta einpoklum 18.05.2018 - 20:18

9 respuestas

164

Algunas técnicas útiles:

  • Activa -Wall y -Werror . Puede parecer contrario a la intuición cuando está luchando con descifrar mensajes de error para crear incluso mensajes de error más , pero las advertencias suelen ser más fáciles de entender y más cercanas a la fuente real del problema, e ignorarlas puede llevar a errores que son difíciles de entender.
  • Solo intenta corregir el primer error en la lista. A menudo, los errores se combinan entre sí, lo que lleva a que los mensajes de error posteriores no sean realmente errores reales. Arregla uno y recompila. Mejorará la resolución de múltiples mensajes de error cuando adquiera más experiencia.
  • Utilice la versión de compilador más nueva posible. C es un lenguaje extremadamente estable. Por lo tanto, una gran parte de las mejoras en los compiladores más nuevos no es agregar características de lenguaje, sino mejorar la experiencia del desarrollador, incluyendo mejores mensajes de error. Muchas distribuciones de Linux ampliamente utilizadas tienen muy versiones antiguas de gcc por defecto.
  • Programa incrementalmente. No intentes escribir una tonelada de código antes de compilar. Escribe la menor cantidad posible que aún se compilará. Si solo ha cambiado una línea desde la última vez que se compiló de forma limpia, es mucho más fácil averiguar qué línea contiene el problema real.
  • Escribir pruebas unitarias. Le da más confianza para realizar cambios de refactorización cuando se corrigen errores de compilación.
respondido por el Karl Bielefeldt 18.05.2018 - 22:09
56

Tu amigo no necesita un glosario. Un glosario no lo ayudará. Lo que necesita es una mejor intuición sobre qué hacer cuando se producen errores de compilación.

Los errores del compilador de C no son tan intuitivos como, por ejemplo, los errores del compilador de C #, por muchas razones principalmente relacionadas con la naturaleza "cercana al metal" de C. Resolver los errores del compilador en C no es un ejercicio de comparación de patrones, porque el error que recibe puede no tener nada que ver con el problema real. A diferencia de C # o Java, donde un mensaje de error generalmente se asigna a una ubicación y problema de código precisos, es probable que los errores en C sean numerosos y lejanos.

Un ejemplo de esto es "se espera un punto y coma" o cualquier número de errores de sintaxis que indiquen que el analizador se ha bloqueado en algo (no necesariamente un punto y coma). O algo así como "declaración anticipada inesperada", un error que, cuando lo veo, siempre significa que obtuve un error de mayúsculas en uno de mis archivos .h, pero que no apunta al archivo .h como la fuente del problema.

La estrategia de su amigo no debería ser ajustar esto a una lista de errores y soluciones; Debería ser entender la sintaxis y la especificación del lenguaje C lo suficientemente bien como para descubrir cuál es el problema actual .

    
respondido por el Robert Harvey 18.05.2018 - 20:28
26

Una técnica relevante que vale la pena mencionar es usar un segundo compilador. Clang ha invertido en mejores mensajes de error, por ejemplo, pero cualquier forma alternativa de expresar el error puede ser esclarecedor.

Esto es especialmente cierto para el tipo más complejo de errores. Por ejemplo, cuando mezcla dos construcciones similares (no inusuales para principiantes), los compiladores generalmente tienen un problema para generar el mensaje de error correcto. Esto puede causar confusión cuando el compilador da un mensaje de error sobre el uso incorrecto de la construcción A cuando en realidad pretendía construir la B. Un segundo compilador podría inferir que su intención era B.

    
respondido por el MSalters 19.05.2018 - 00:42
12

Alguien hizo un intento de un glosario de errores de GCC en Wikibooks hace tiempo, pero Parece que nunca despegó y no se ha actualizado.

La sección "Errores" es mucho más avanzada que la sección "Advertencias". Parece que estaba dirigido a G ++, pero es probable que todavía haya información útil para su amigo allí.

    
respondido por el nBurn 19.05.2018 - 02:35
12

Además de las respuestas anteriores, tenga en cuenta que la mayoría de los compiladores no tienen glosarios de errores exhaustivos. Esto sería mucho trabajo para mantener ya que los mensajes a menudo cambian, y hay bastante muchos de ellos.

El mejor sustituto para un glosario es el acceso a Internet. Siempre que el compilador produzca un error que no entienda, tenga la seguridad de que es altamente improbable que usted sea el primero en haberlo encontrado y confundido. Un rápido Google del mensaje exacto suele ser suficiente para proporcionarle mucha información en un formato fácil de leer, a menudo con un código de ejemplo muy similar al suyo.

Más allá de eso, todo lo que necesita es tiempo y familiaridad con el lenguaje y el compilador. Eso, y los buenos consejos dados por Karl Bielefeldt .

    
respondido por el Dúthomhas 19.05.2018 - 03:03
6

El estándar C utiliza una serie de términos como "lvalue" y "object" en formas que son diferentes de otros lenguajes de programación, y los mensajes del compilador a menudo se escriben en dichos términos. El uso de la terminología es inconsistente en algunas partes de la Norma, pero cualquier persona que desee aprender C debe consultar los borradores de las normas C89, C99 y / o C11, así como los documentos de justificación de las mismas. Buscando por ejemplo El "borrador de C99" o la "justificación de C89" deberían funcionar bastante bien, aunque es posible que deba asegurarse de obtener el documento que espera. Aunque la mayoría de los compiladores son compatibles con el estándar C99, puede ser útil saber en qué se diferencia del estándar C89, y la lógica del C89 puede ofrecer algunos antecedentes históricos que las versiones posteriores no admiten.

    
respondido por el supercat 19.05.2018 - 01:00
5

Me sorprende que nadie haya dado la respuesta obvia y, sospecho, la que más se usa en la práctica: simplemente no lea los mensajes de error.

La gran mayoría del valor de la mayoría de los mensajes de error es simplemente que algo está mal en tal o cual línea. La mayoría de las veces solo miro el número de línea y voy a esa línea. Mi "lectura" del mensaje de error en ese punto es generalmente lo que mis ojos captan al pasar, ni siquiera un vistazo. Si no se aclara inmediatamente lo que está mal en la línea o cerca de ella, leeré el mensaje. Este flujo de trabajo es aún mejor con un IDE o herramientas que resaltan los errores en el lugar y automáticamente cumplen con la sugerencia de Karl Bielefeldt de considerar solo pequeños cambios.

Por supuesto, los mensajes de error no siempre apuntan a la línea apropiada, pero a menudo tampoco apuntan a la causa raíz apropiada, por lo que incluso una comprensión completa del mensaje de error sería de ayuda limitada. No toma mucho tiempo para tener una idea de qué mensajes de error son más confiables para localizar la línea adecuada.

Por un lado, la mayoría de los errores que probablemente cometa un novato probablemente sean dolorosamente obvios para un programador experimentado, sin que sea necesaria la ayuda del compilador. Por otro lado, es mucho menos probable que sean tan obvios para el principiante (aunque muchos serán obvios, la mayoría de los errores son errores estúpidos). En este punto estoy completamente de acuerdo con Robert Harvey, el principiante simplemente necesita familiarizarse con el idioma. No hay forma de evitar esto. Los errores del compilador que hacen referencia a conceptos desconocidos o que parecen sorprendentes deben verse como indicaciones para profundizar los conocimientos del idioma. De manera similar, en los casos en que el compilador se queja, pero no puede ver por qué el código es incorrecto.

De nuevo, estoy de acuerdo con Robert Harvey en que se necesita una mejor estrategia para utilizar los errores del compilador. He esbozado algunos aspectos arriba y la respuesta de Robert Harvey da otros aspectos. Ni siquiera está claro qué espera hacer tu amigo con un "glosario" de este tipo, y es muy poco probable que dicho "glosario" sea realmente útil para tu amigo. Los mensajes del compilador ciertamente no son el lugar para una introducción a los conceptos del lenguaje 1 y un "glosario" no es un lugar mucho mejor para él. Incluso con una descripción clara de lo que significa el mensaje de error, no te dirá cómo arreglar el problema.

1 Sin embargo, algunos lenguajes, como Elm y Dhall (y probablemente Racket), así como algunas implementaciones de lenguajes "orientadas a principiantes" intentan hacer esto. En este sentido, el consejo de MSalters para utilizar una implementación diferente es directamente relevante. Personalmente, considero que esas cosas no son convincentes y no están dirigidas del todo al problema correcto. Esto no quiere decir que no haya formas de hacer mejores mensajes de error, pero, para mí, tienden a girar en torno a aclarar las creencias del compilador y la base de esas creencias.

    
respondido por el Derek Elkins 20.05.2018 - 12:08
4
  

Entonces, ¿cómo debería un programador novato abordar el desafío de comprender los mensajes de error del compilador? Específicamente, con la combinación de C y GCC?

Dígale a su amigo que haga lo siguiente cuando encuentre un error que no entienden:

  • Eliminar / comentar el código agregado desde la última compilación exitosa.
  • Vuelva a colocar las partes pequeñas y compile
  • Repita hasta que se produzca el error

Los errores del compilador solo le dicen lo que el compilador no entiende acerca de su código, no lo que está mal con él. Este enfoque lleva aproximadamente la misma cantidad de tiempo que buscar en Google el error y leer algunos documentos o una publicación de StackOverflow, pero proporciona una mejor comprensión de qué es lo que estás haciendo mal.

También haga que se compilen con frecuencia hasta que comiencen a trabajar en proyectos que demoran minutos en construirse, detectar errores antes de agregar demasiado otro código ayuda mucho.

Finalmente, dígales que trabajen en una cosa a la vez, no trabajen en varios archivos sin compilar entre ellos, no introduzcan múltiples dependencias a la vez, etc.

    
respondido por el Kevin 19.05.2018 - 14:35
4

Otra técnica sería que el amigo escriba su propio glosario a lo largo del tiempo, ya que se encuentra con diferentes mensajes de error. A menudo, la mejor manera de aprender algo es enseñarlo. Por supuesto, para cuando se haga el glosario, es probable que ya no lo necesite.

Mi experiencia personal con GCC es que cada mensaje de error se relaciona con un conjunto "habitual" de errores. Por ejemplo, cuando GCC dice "¿olvidó el &" por lo general significa que me olvidé de paréntesis. Por supuesto, qué errores corresponden a qué mensajes de error dependerán del programador, otra buena razón para que el amigo escriba su propio glosario.

    
respondido por el Owen 20.05.2018 - 15:10

Lea otras preguntas en las etiquetas