programming code compiler-construction

compiler-construction - code - interpreter programming



¿Cuánto del compilador deberíamos saber? (13)

Para escribir un mejor código, ¿vale la pena conocer en profundidad qué hace el compilador?

¿Cuánto sería suficiente? No soy un poco depravado, pero estaba pensando que saber cómo funciona el compilador me haría un mejor programador. ¿Me equivoco?

Si es así, ¿qué recursos recomendarías?


¿Tiene algún interés en utilizar efectivamente un depurador? Entonces sí. ¿Tiene algún interés en escribir un código confiable o eficiente? Entonces sí.

Personalmente me importa más el backend que el frontend. Recomiendo compilar para ARM en lugar de x86, en este caso no estás aprendiendo assembler necesariamente (donde recomiendo escribir tu propio desensamblador), así que si usas gcc tiene un desensamblador y puedes ver lo que hace tu código de alto nivel para cambiar el resultado final, así como la cantidad de cambio que puede hacer con las opciones del compilador. Es una experiencia reveladora para la mayoría de los programadores de lenguaje de alto nivel darse cuenta de que el mismo código puede tener resultados tremendamente diferentes en función del compilador y las opciones de línea de comando utilizadas.

Para la mitad del compilador, recomiendo tanto lcc como sdcc. Puede o no querer comprar el libro de lcc:

[ http://www.cs.princeton.edu/software/lcc/][1]

No necesita, sin embargo, la fuente está en la red (en muchas formas). Como es sdcc (compilador de dispositivo pequeño c, creado originalmente para el 8051 y otros micros de 8 bits). Mi recomendación es entrar en la interfaz donde el compilador se encuentra con el back-end, encontrará que su código se ha convertido en una serie de partes atómicas, a veces como pulido inverso. a = b + 7; podría terminar siendo cargar el entero constante 7. leer de memoria la variable b en los siguientes registros disponibles. Agregue 7 más el registro con by guarde en el siguiente registro disponible. almacenar el valor en el registro de la ubicación en la memoria para a.

También puedes hacer esto con gcc, pero puedes terminar dándote cuenta de que gcc no es tan genial como lo era. Debido a la cantidad de idiomas, el número de backends y el número de manos en la mezcla, etc., es enorme y complicado. Sin embargo, funciona y funciona para los idiomas y las plataformas que mantienen los expertos. Lo que gcc puede enseñarte que los otros no pueden es que los diversos idiomas de la interfaz se reduzcan a un lenguaje intermedio común que la parte de atrás se convierte en instrucciones específicas para cada plataforma.

Por último, la interfaz. La mayoría de las personas utilizan bison / yacc, que es una herramienta que crea una descripción para su lenguaje de alto nivel y la herramienta puede analizar la entrada del usuario en función de su descripción y convertirla en este segundo idioma, si así lo desea.

Si piensas en tu hobby o carrera profesional que tiene que ver con escribir software, diría que debes realizar este ejercicio una vez, si no muchas veces. La calidad general de su código, la confiabilidad de su código, el rendimiento de su código y el código de escritura de eficiencia se verán afectados por este conocimiento.

Sería cuidadoso con la afirmación "no escriba para el compilador, pero escriba para que las personas lean". Hay un montón de código incorrecto porque ese tipo de declaración se usa mal. El código de escritura para la mantenibilidad da como resultado un código incorrecto que debe mantenerse. La capacidad de mantenimiento es mutuamente exclusiva con fiabilidad y rendimiento. Personalmente, tengo confiabilidad y rendimiento que el código incorrecto que cualquier graduado de la universidad puede mantener.

Con el tiempo, aprenderá a no esforzarse demasiado por escribir para el compilador. No desperdicies tu código, no uses las mejores características del lenguaje. Si tuviera que investigar más para descubrir alguna característica del compilador, puede estar seguro de que la mayoría del mundo no lo comprende, incluida la persona que se supone debe implementarlo en los compiladores. Por lo tanto, puede esperar que esa característica no funcione de manera consistente en todos los compiladores, por lo tanto, debe usarla en primer lugar. Esto también significa que no intente escribir su código para un compilador específico, no se apegue demasiado a gcc y sus características, pruebe sdcc y lcc y microsoft y borland y kiel y otros. Haga que su código sea limpio, simple, legible y portátil.

En pocas palabras, si realmente quiere escribir software, es absolutamente necesario que sepa cómo funciona el compilador. gcc, sdcc, lcc, (y vbcc si puede encontrarlo) son todos gratuitos, de código abierto y proporcionan una experiencia de aprendizaje que mejorará sus habilidades de codificación.


Como mínimo, debe estar familiarizado con las características del idioma en un nivel abstracto. Si no sabe si los nombres de las variables distinguen entre mayúsculas y minúsculas, o cómo se convierten los números a boolean, entonces probablemente ni siquiera pueda escribir una cláusula ''si'' fiable de forma fiable.

Sobre todo, he descubierto que cualquier otro conocimiento sobre el funcionamiento interno de un compilador solo me ayuda a escribir un código más eficiente.


Creo que cada programador debe tener un conocimiento básico de cómo un compilador convierte su código de alto nivel en instrucciones de máquina, optimizaciones que se pueden realizar, cómo funciona la memoria y cómo se ejecuta el código en el hardware. Creo que es útil tener esto en cuenta para que entienda mejor el rendimiento de su programa y pueda ayudarlo a tomar mejores decisiones de implementación.

Probablemente no sea crítico que pueda escribir código de máquina o saber exactamente qué arquitectura de memoria virtual utiliza su sistema, pero creo que es importante una idea básica de estos conceptos.

EDITAR

Por ejemplo: los compiladores de C almacenan datos en matrices en formato principal de filas, por lo que debe iterar sobre matrices multidimensionales que varíen primero la dimensión más alta (índice de más a la derecha) y luego proceda a la dimensión más baja (índice de más a la izquierda). Fortran hace exactamente lo contrario, almacenando matrices en formato columna principal. Esto significa que en Fortran debes variar primero la dimensión más baja, yendo a la dimensión más alta. Esto mejorará la proporción de aciertos de caché de su código y mejorará significativamente el rendimiento de las matrices multidimensionales grandes.


Creo que definitivamente te hará un mejor programador, de una manera sutil.

Una comprensión general de cómo funciona le ayudará a estar más al tanto del código que está escribiendo. He visto muchos desarrolladores experimentados que luchan por comprender algunos conceptos fundamentales al aprender un nuevo idioma. Si sabe aproximadamente cómo funciona un compilador y (tal vez más importante) cómo se ejecuta el código, comprenderá mejor estos conceptos. Estoy hablando de Heap vs stack, punteros, etc.

También puede ser útil si necesita escribir código para analizar o traducir texto. Una vez escribí un programa para traducir algunas condiciones sql a otro formato personalizado y escribir un pequeño analizador porque era la manera más simple y elegante de hacerlo (o eso creo :))

Además, una comprensión profunda de un compilador puede ayudarlo a optimizarlo específicamente, pero eso puede ser muy difícil y no siempre recomendable, como dijo Coobird.


Creo que lo que hace el compilador es lo importante aquí (crea una explicación con las características x, y, z) Eso se traduce en conocer la plataforma a la que se dirige.

La forma en que hace esa tarea es irrelevante (a menos que esté escribiendo compiladores por supuesto)

Lo más importante que debemos saber sobre un compilador son los mensajes de error que muestra.

:) Parece obvio, pero estoy sorprendido por la cantidad de desarrolladores que he conocido que ni siquiera miraron la salida del compilador.


Creo que lo realmente importante es hacer un intérprete: te da más información sobre los lenguajes de programación, y eso es lo que usas ... En el esquema, ¡no es realmente difícil hacer un interperador! Pero en realidad, me gustaría animar mucho a leer partes del SICP para una gran iluminación).

Con respecto a los compiladores, es más complejo ya que el enfoque aquí es obtener algún rendimiento / hacerlo para una máquina real. Como programador, lo importante es saber al menos qué tareas desempeñan globalmente y cuándo funcionan en lugar de los detalles, porque hoy en día se han convertido en sistemas realmente complejos, especialmente con JIT, etc.


En una publicación de blog, Steve Yegge afirmó que todos los programadores deberían saber cómo funcionan los compiladores . Él va tan lejos como para decir:

Resumen ejecutivo suave, pero insistente: si no sabe cómo funcionan los compiladores, entonces no sabe cómo funcionan las computadoras. Si no está 100% seguro de saber cómo funcionan los compiladores, entonces no sabe cómo funcionan.

En el artículo, él hace un argumento convincente para necesitar saber compiladores. También proporciona una lista de ejemplos del mundo real donde sería útil saber cómo analizar y analizar.


He enseñado tanto lenguajes de programación como compiladores avanzados. Estos son los dos motivos más útiles para saber qué hace el compilador:

  1. Si no tiene idea de lo que está haciendo el compilador, puede escribir inadvertidamente un código que es mucho más caro de lo que esperaba. Esto es especialmente cierto si está asignando memoria sin saberlo. Un ejemplo clásico es concatenar cadenas en un bucle, por ejemplo, como en

    answer = ""

    para i = 1 a n hacer

    answer = answer .. strings[i] -- .. is string concatenation

    Este código es cuadrático, haciendo una cantidad cuadrática de asignación y copia. Malas noticias.

  2. La otra gran razón para saber algo sobre los compiladores es que a menudo un problema requiere un poco de lenguaje. Si sabes algo sobre los compiladores (los intérpretes son igual de buenos aquí, probablemente sean mejores), entonces puedes construir un pequeño lenguaje. Si puede elegir cómo se ve el idioma, a menudo es mejor dejar que otra persona construya el idioma por usted. Lua es un lenguaje que es particularmente bueno para ser utilizado como componente por otros programas.

El tutorial de Crenshaw no está mal. Otro buen libro, si puedes tenerlo en tus manos, es el libro de PJ Brown sobre compiladores e intérpretes interactivos. Ya se agotó, pero es posible que lo encuentres en una biblioteca.

Evitaría los muchos libros de texto universitarios sobre compiladores. Un texto de estudiante gordo que puede ser más valioso para el compilador-curioso es Programming-Language Pragmatics de Michael Scott.


No aprenda compiladores, aprenda los problemas resueltos por ellos.


No creo que sea tan necesario saber cómo funciona un compilador sino mejorar continuamente el conocimiento sobre programación. Ahora, sucede que aprender a escribir un compilador (o los principios que lo sustentan) es una gran manera de expandir el conocimiento.

Si está interesado, recomendaría obtener el Libro del Dragón, también conocido como compiladores: Principios, técnicas y herramientas . Puede ser un poco pesado la primera vez, pero sin duda te hará pensar. Si no logra atravesar o quedarse atascado en algunas partes, le sugiero que las deje de lado por un momento y luego regrese; es mucho más fácil pasar la segunda vez.


Para ser verdaderamente completo como desarrollador, creo que debería saber bastante sobre los compiladores en general y cómo funcionan, tal vez incluso intente escribir uno simple.

Para los compiladores específicos, sin embargo, la mayoría de los desarrolladores pueden escaparse sabiendo solo una cosa: el compilador cambia al lenguaje ensamblador de salida en lugar de al código binario. Examinar el lenguaje de ensamblado generado le dirá exactamente qué está haciendo el compilador para optimizar su código y puede ayudarlo a descubrir cómo volver a escribir el código para que funcione aún mejor.
Además, es divertido "ejercicio del programador" para actualizar su conocimiento de bajo nivel.


Probablemente no estaría de más saber cómo el compilador optimizará su código, pero no escriba para el compilador, sino que escriba para que la gente lo lea .

Escribir el código de una manera que esté más optimizada para el compilador puede hacer que sea más difícil para las personas leerlo, y en estos días el compilador probablemente sabe mejor para optimizar el código para usted .


Sin ninguna prueba de efectividad en absoluto, me siento mejor al entender lo que sucede con mi código por saber un poco sobre compiladores y un poco de ensamblaje. Puede aprender mucho leyendo el Compilador de Let''s Build de Jack Crenshaw .

Entonces, puede buscar métodos de compilación más sofisticados si está interesado.

Editar: También vale la pena señalar que una gran cantidad de problemas que no requieren un "compilador" siguen siendo mejor atendidos por los métodos del compilador. Analizar cualquier lenguaje de comandos modestamente complicado es un problema de compilación, incluso si no está escribiendo un ejecutable.

Edit2: Muchos de los textos habituales adoptan un enfoque matemático bastante abstracto para el problema del compilador, que puede ser intimidante o confuso al principio. El tutorial de Crenshaw adopta un enfoque de "comenzar a golpear el código" que está informado por la comprensión más sutil del autor. Bonita introducción, pero si habla en serio, debe hacer un seguimiento con un estudio más formal.