Actualmente C se considera un lenguaje de bajo nivel , pero en los años 70 ¿se consideraba de bajo nivel? ¿Estaba el término incluso en uso entonces?
Muchos lenguajes populares de alto nivel no existieron hasta mediados de los 80 y más allá, así que tengo curiosidad por saber cómo y cómo la naturaleza del bajo nivel ha cambiado a lo largo de los años.
programming-languages
c
history
joeyfb
fuente
fuente
Respuestas:
Para responder a los aspectos históricos de la pregunta:
La filosofía de diseño se explica en El lenguaje de programación C escrito por Brian Kernighan y el diseñador C Dennis Ritchie, el "K&R" del que quizás haya oído hablar. El prefacio de la primera edición dice
y la introducción dice
La lista continúa por un tiempo antes de que el texto continúe:
(Solo tengo la segunda edición de 1988, pero el comentario a continuación indica que el texto citado es el mismo en la primera edición de 1978).
Entonces, sí, los términos "alto nivel" y "bajo nivel" estaban en uso en ese entonces, pero C fue diseñado para caer en algún lugar del espectro intermedio. Era posible escribir código en C que fuera portátil a través de plataformas de hardware, y ese era el criterio principal para determinar si un lenguaje se consideraba de alto nivel en ese momento. Sin embargo, C carecía de algunas características que eran características de los lenguajes de alto nivel, y esta fue una decisión de diseño a favor de la simplicidad.
fuente
Esto depende de su definición de lenguaje de alto y bajo nivel. Cuando se desarrolló C, todo lo que era de nivel superior al ensamblado se consideraba un lenguaje de alto nivel. Esa es una barra baja para despejar. Más tarde, esta terminología cambió al punto de que algunos hoy en día considerarían incluso a Java como un lenguaje de bajo nivel.
Incluso dentro del panorama lingüístico de alto nivel de los años 70, vale la pena señalar que C tiene un nivel bastante bajo. El lenguaje C es básicamente B más un sistema de tipo simple, y B no es mucho más que una conveniente capa de sintaxis procesal / estructurada para el ensamblaje. Debido a que el sistema de tipos es un ajuste posterior en la parte superior del lenguaje B sin tipo, aún puede omitir anotaciones de tipo en algunos lugares y
int
se supondrá.C omite conscientemente funciones costosas o difíciles de implementar que ya estaban bien establecidas en ese momento, como
C tiene algunas características interesantes:
En el momento en que se desarrolló C, otros lenguajes innovadores como COBOL, Lisp, ALGOL (en varios dialectos), PL / I, SNOBOL, Simula y Pascal ya se habían publicado y / o se usaban ampliamente para dominios con problemas específicos. Pero la mayoría de esos idiomas existentes estaban destinados a la programación de mainframe, o eran proyectos de investigación académica. Por ejemplo, cuando ALGOL-60 se diseñó por primera vez como un lenguaje de programación universal, la tecnología y la informática necesarias para implementarlo aún no existían. Algunos de estos (algunos dialectos ALGOL, PL / I, Pascal) también estaban destinados a la programación de bajo nivel, pero tendían a tener compiladores más complejos o eran demasiado seguros (por ejemplo, sin punteros sin restricciones). Pascal carece notablemente de un buen soporte para matrices de longitud variable.
En comparación con esos lenguajes, C rechaza las características "elegantes" y caras para ser más práctico para el desarrollo de bajo nivel. C nunca fue principalmente un proyecto de investigación de diseño de lenguaje. En cambio, fue una rama del desarrollo de kernel de Unix en el minicomputador PDP-11 que estaba relativamente limitado en recursos. Por su nicho (un lenguaje minimalista de bajo nivel para escribir Unix con un compilador de un solo paso que es fácil de portar) C se destacó por completo, y más de 45 años después sigue siendo la lengua franca de la programación de sistemas.
fuente
%r10
como el "puntero de cadena estática", que es exactamente de lo que estás hablando. Para C es solo otro registro de scratch con capa de llamada, pero supongo que Pascal lo usaría. (Las funciones anidadas de GNU C lo usan para pasar un puntero al ámbito externo cuando dicha función no está en línea (por ejemplo, si hace un puntero de función para que el compilador cree un trampolín de código de máquina en la pila): Aceptabilidad de regular uso de r10 y r11 )a = b;
para copiar una estructura completa de la manera que puede en ISO C89. Entonces, a principios de C, los tipos definidos por el usuario eran definitivamente de segunda clase y solo podían pasarse por referencia como argumentos de función. La aversión de C a las matrices y también ¿Por qué C ++ admite la asignación de matrices dentro de las estructuras por parte de los miembros, pero generalmente no?A principios de la década de 1970, C era un soplo de aire fresco deslumbrante que usaba construcciones modernas de manera tan efectiva que todo el sistema UNIX podía reescribirse desde lenguaje ensamblador a C con espacio insignificante o penalización de rendimiento. En ese momento, muchos contemporáneos se referían a él como un lenguaje de alto nivel.
Los autores de C, principalmente Dennis Ritchie, fueron más circunspectos y en el artículo de Bell System Technical Journal dijeron que "C no es un lenguaje de muy alto nivel". Con una sonrisa irónica y con la intención de ser provocativo, Dennis Ritchie diría que era un lenguaje de bajo nivel. El principal de sus objetivos de diseño para C era mantener el lenguaje cerca de la máquina y proporcionar portabilidad, es decir, independencia de la máquina.
Para más información consulte el artículo original de BSTJ:
Gracias Dennis Que descanse en paz.
fuente
Como escribí en otra parte de este sitio cuando alguien se refirió al patrón de administración de memoria libre / malloc como "programación de bajo nivel"
Para el contexto, esto fue a principios de los 90, mucho después de que salió C.
fuente
malloc()
llamar directamentebrk(2)
ommap(2)
administrar la memoria resultante usted mismo. Es un PITA masivo sin ningún beneficio concebible (a menos que esté implementando algo similar a Malloc), pero puede hacerlo.Muchas respuestas ya se han referido a los primeros artículos que decían cosas como "C no es un lenguaje de alto nivel".
Sin embargo, no puedo resistirme a la acumulación: muchos, si no la mayoría o todos los HLL en ese momento, Algol, Algol-60, PL / 1, Pascal, proporcionaron la verificación de los límites de la matriz y la detección de desbordamiento numérico.
La última vez que verifiqué los desbordamientos de búfer y enteros fueron la causa raíz de muchas vulnerabilidades de seguridad. ... Sí, sigue siendo el caso ...
La situación para la administración dinámica de la memoria fue más complicada, pero aún así, el estilo C malloc / free fue un gran paso atrás en términos de seguridad.
Entonces, si su definición de HLL incluye "evita automáticamente muchos errores de bajo nivel", bueno, el lamentable estado de ciberseguridad sería muy diferente, probablemente mejor, si C y UNIX no hubieran sucedido.
fuente
popcnt
.Considere los lenguajes más antiguos y mucho más antiguos que precedieron a C (1972):
Fortran - 1957 (nivel no mucho más alto que C)
Lisp - 1958
Cobol - 1959
Fortran IV - 1961 (nivel no mucho más alto que C)
PL / 1 - 1964
APL - 1966
Además de un lenguaje de nivel medio como RPG (1959), principalmente un lenguaje de programación para reemplazar los sistemas de grabación de unidades basados en el tablero.
Desde esta perspectiva, C parecía un lenguaje de muy bajo nivel, solo un poco por encima de los macro ensambladores utilizados en mainframes en ese momento. En el caso de los mainframes de IBM, las macros ensambladoras se usaron para el acceso a la base de datos, como BDAM (método básico de acceso al disco), ya que las interfaces de la base de datos no se habían portado a Cobol (en ese momento), lo que resultó en un legado de una combinación de ensamblaje y Los programas de Cobol todavía están en uso hoy en mainframes de IBM.
fuente
La respuesta a su pregunta depende de qué lenguaje C está preguntando.
El lenguaje descrito en el Manual de referencia C de 1974 de Dennis Ritchie era un lenguaje de bajo nivel que ofrecía algunas de las ventajas de programación de los lenguajes de nivel superior. Los dialectos derivados de ese lenguaje también tienden a ser lenguajes de programación de bajo nivel.
Sin embargo, cuando se publicó el estándar C 1989/1990, no describía el lenguaje de bajo nivel que se había vuelto popular para programar máquinas reales, sino que describía un lenguaje de nivel superior que podría ser, pero no era obligatorio, -implementado en términos de nivel inferior.
Como señalan los autores de la Norma C, una de las cosas que hizo útil el lenguaje fue que muchas implementaciones podrían tratarse como ensambladores de alto nivel. Debido a que C también se usó como una alternativa a otros lenguajes de alto nivel, y debido a que muchas aplicaciones no requerían la capacidad de hacer cosas que los lenguajes de alto nivel no podían hacer, los autores del Estándar permitieron que las implementaciones se comportaran de manera arbitraria si los programas intentaron usar construcciones de bajo nivel. En consecuencia, el lenguaje descrito por el Estándar C nunca ha sido un lenguaje de programación de bajo nivel.
Para comprender esta distinción, considere cómo Ritchie's Language y C89 verían el fragmento de código:
en una plataforma donde "char" tiene 8 bits, "int" tiene 16 bits big-endian, "float" tiene 32 bits y las estructuras no tienen requisitos especiales de relleno o alineación, por lo que el tamaño de "struct foo" es de 8 bytes.
En el lenguaje de Ritchie, el comportamiento de la última declaración tomaría la dirección almacenada en "p", le agregaría 3 * 8 + 2 [es decir, 26] bytes y buscaría un valor de 16 bits de los bytes en esa dirección y la siguiente , agregue uno a ese valor y luego vuelva a escribir ese valor de 16 bits en los mismos dos bytes. El comportamiento se definiría como actuar sobre los bytes 26 y 27 que siguen al de la dirección p sin tener en cuenta qué tipo de objeto estaba almacenado allí.
En el lenguaje definido por el Estándar C, en el caso de que * p identifique un elemento de un "struct foo []" seguido de al menos tres elementos completos más de ese tipo, la última instrucción agregaría uno al miembro y de El tercer elemento después de * p. El comportamiento no sería definido por el Estándar bajo ninguna otra circunstancia.
El lenguaje de Ritchie era un lenguaje de programación de bajo nivel porque, si bien permitía a un programador usar abstracciones como matrices y estructuras cuando era conveniente, definía el comportamiento en términos del diseño subyacente de los objetos en la memoria. Por el contrario, el lenguaje descrito por C89 y estándares posteriores define las cosas en términos de una abstracción de nivel superior, y solo define el comportamiento del código que es consistente con eso. Las implementaciones de calidad adecuadas para la programación de bajo nivel se comportarán de manera útil en más casos que los exigidos por el Estándar, pero no existe un documento "oficial" que especifique qué debe hacer una implementación para ser adecuada para tales fines.
El lenguaje C inventado por Dennis Ritchie es, por lo tanto, un lenguaje de bajo nivel, y fue reconocido como tal. Sin embargo, el lenguaje inventado por el Comité de Normas C nunca ha sido un lenguaje de bajo nivel en ausencia de garantías proporcionadas por la implementación que vayan más allá de los mandatos de la Norma.
fuente