stringtranslate.com

Ciclón (lenguaje de programación)

El lenguaje de programación Cyclone estaba destinado a ser un dialecto seguro del lenguaje C. Evita desbordamientos de búfer y otras vulnerabilidades que son posibles en los programas C por diseño, sin perder el poder y la conveniencia de C como herramienta para la programación del sistema . Sus desarrolladores originales ya no lo admiten y las herramientas de referencia no son compatibles con plataformas de 64 bits . Los desarrolladores originales mencionan el lenguaje Rust por haber integrado muchas de las mismas ideas que tenía Cyclone. [2]

El desarrollo de Cyclone se inició como un proyecto conjunto de AT&T Labs Research y el grupo de Greg Morrisett en la Universidad de Cornell en 2001. La versión 1.0 se lanzó el 8 de mayo de 2006. [3]

Características del idioma

Cyclone intenta evitar algunos de los errores comunes de C , manteniendo al mismo tiempo su apariencia y rendimiento. Con este fin, Cyclone impone los siguientes límites a los programas:

Para mantener el conjunto de herramientas al que están acostumbrados los programadores de C, Cyclone proporciona las siguientes extensiones:

Para obtener una mejor introducción de alto nivel a Cyclone, el razonamiento detrás de Cyclone y el origen de estas listas, consulte este documento.

Cyclone se parece, en general, a C, pero debe verse como un lenguaje similar a C.

Tipos de puntero

Cyclone implementa tres tipos de puntero :

El propósito de introducir estos nuevos tipos de punteros es evitar problemas comunes al utilizar punteros. Tomemos, por ejemplo, una función llamada fooque toma un puntero a un int:

 intfoo ( int * ) ;  

Aunque la persona que escribió la función foopodría haber insertado NULLcheques, supongamos que por razones de rendimiento no lo hizo. La llamada foo(NULL);dará como resultado un comportamiento indefinido (normalmente, aunque no necesariamente, se envía una señal SIGSEGV a la aplicación). Para evitar este tipo de problemas, Cyclone introduce el tipo de puntero, que nunca puede ser . Así, la versión "segura" de sería:@NULLfoo

 intfoo ( int @ ) ;  

Esto le dice al compilador de Cyclone que el argumento foonunca debe ser NULL, evitando el comportamiento indefinido antes mencionado. El simple cambio de *a @evita que el programador tenga que escribir NULLcomprobaciones y que el sistema operativo tenga que atrapar NULLdesreferencias de puntero. Este límite adicional, sin embargo, puede ser un obstáculo bastante grande para la mayoría de los programadores de C, que están acostumbrados a poder manipular sus punteros directamente con aritmética. Aunque esto es deseable, puede provocar desbordamientos del buffer y otros errores tipo "uno por uno". Para evitar esto, el ?tipo de puntero está delimitado por un límite conocido, el tamaño de la matriz. Aunque esto agrega una sobrecarga debido a la información adicional almacenada sobre el puntero, mejora la seguridad. Tomemos, por ejemplo, una función simple (e ingenua) strlen, escrita en C:

 int strlen ( const char * s ) { int i = 0 ; si ( s == NULL ) devuelve 0 ; mientras ( s [ i ] ! = '\0' ) { i ++ ; } devolver yo ; }                        

Esta función supone que la cadena que se pasa termina en NULL( '\0'). Sin embargo, ¿qué pasaría si se pasara a esta cadena? Esto es perfectamente legal en C, pero provocaría una iteración a través de la memoria no necesariamente asociada con la cadena . Hay funciones, como las que se pueden utilizar para evitar tales problemas, pero estas funciones no son estándar en todas las implementaciones de ANSI C. La versión Cyclone no es tan diferente de la versión C:char buf[6] = {'h','e','l','l','o','!'};strlensstrnlenstrlen

 int strlen ( const char ? s ) { int i , n = s . tamaño ; si ( s == NULL ) devuelve 0 ; para ( i = 0 ; i < n ; i ++ , s ++ ) si ( * s == '\0' ) devuelve i ; devolver norte ; }                                  

Aquí, strlense limita a la longitud de la matriz que se le pasa, por lo que no supera la longitud real. Cada uno de los tipos de puntero se puede convertir de forma segura a cada uno de los demás, y ?el compilador convierte automáticamente las matrices y cadenas . (Lanzar desde ?a *invoca una verificación de límites , y lanzar desde ?a @invoca tanto una NULLverificación como una verificación de límites. Lanzar desde *a ?no da como resultado ninguna verificación; el ?puntero resultante tiene un tamaño de 1).

Indicadores pendientes y análisis de regiones

Considere el siguiente código, en C:

 char * itoa ( int i ) { char buf [ 20 ]; sprintf ( buf , "%d" , i ); devolver buf ; }         

La función itoaasigna una matriz de caracteres bufen la pila y devuelve un puntero al inicio de buf. Sin embargo, la memoria utilizada en la pila bufse desasigna cuando la función regresa, por lo que el valor devuelto no se puede usar de manera segura fuera de la función. Si bien GNU Compiler Collection y otros compiladores advertirán sobre dicho código, lo siguiente normalmente se compilará sin advertencias:

 char * itoa ( int i ) { char buf [ 20 ], * z ; sprintf ( buf , "%d" , i ); z = buf ; devolver z ; }             

La colección de compiladores GNU puede generar advertencias para dicho código como efecto secundario de la opción -O2o -O3, pero no hay garantías de que se detecten todos esos errores. Cyclone realiza un análisis regional de cada segmento de código, evitando punteros colgantes, como el que devuelve esta versión de itoa. Todas las variables locales en un ámbito determinado se consideran parte de la misma región, separada del montón o de cualquier otra región local. Por lo tanto, al analizar itoa, el compilador de Cyclone vería que zes un puntero a la pila local e informaría un error.

Ver también

Referencias

  1. ^ "Revistas Cyclone (lenguaje de programación) de acceso abierto · OA.mg". oa.mg.
  2. ^ "Ciclón". cyclone.thelanguage.org . Consultado el 11 de diciembre de 2023 .
  3. ^ "Ciclón". Universidad de Cornell .

enlaces externos

Presentaciones: