El ciclón lenguaje de programación está destinada a ser un dialecto segura del lenguaje C . Cyclone está diseñado para evitar desbordamientos de búfer y otras vulnerabilidades que son posibles en los programas C, sin perder el poder y la conveniencia de C como herramienta para la programación del sistema .
Diseñada por | Laboratorios de AT&T |
---|---|
Apareció por primera vez | 2002 |
Lanzamiento final | 1.0 / 8 de mayo de 2006 |
Sitio web | ciclón |
Influenciado por | |
C | |
Influenciado | |
Rust , Proyecto Verona |
El desarrollo de Cyclone se inició como un proyecto conjunto de AT&T Labs Research y el grupo de Greg Morrisett en Cornell en 2001. La versión 1.0 fue lanzada el 8 de mayo de 2006.
Características del idioma
Cyclone intenta evitar algunos de los errores comunes de C , sin dejar de mantener su apariencia y rendimiento. Con este fin, Cyclone impone los siguientes límites a los programas:
NULL
Se insertan controles para evitar fallas de segmentación.- La aritmética de punteros es limitada
- Los punteros deben inicializarse antes de su uso (esto se aplica mediante un análisis de asignación definido )
- Los punteros colgantes se evitan mediante el análisis de la región y los límites en
free()
- Solo se permiten moldes y uniones "seguras"
goto
en ámbitos no está permitidoswitch
No se permiten etiquetas en diferentes ámbitos.- Las funciones de retorno de puntero deben ejecutarse
return
setjmp
ylongjmp
no son compatibles
Para mantener el conjunto de herramientas al que están acostumbrados los programadores de C, Cyclone proporciona las siguientes extensiones:
- Los Never-
NULL
pointers no requierenNULL
controles - Los punteros "gordos" admiten la aritmética de punteros con verificación de límites en tiempo de ejecución
- Las regiones de crecimiento admiten una forma de gestión de memoria manual segura
- Recolección de basura para valores asignados al montón
- Las uniones etiquetadas admiten argumentos que varían de tipo
- Las inyecciones ayudan a automatizar el uso de uniones etiquetadas para programadores
- El polimorfismo reemplaza algunos usos de
void *
- los varargs se implementan como punteros gordos
- Las excepciones reemplazan algunos usos de
setjmp
ylongjmp
Para una mejor introducción de alto nivel a Cyclone, el razonamiento detrás de Cyclone y la fuente de estas listas, consulte este documento .
Cyclone se parece, en general, a C , pero debería verse como un lenguaje similar a C.
Tipos de puntero
Cyclone implementa tres tipos de puntero :
*
(el tipo normal)@
(el nuncaNULL
puntero), y?
(el único tipo con aritmética de punteros permitida, punteros "gordos" ).
El propósito de presentar estos nuevos tipos de punteros es evitar problemas comunes al usar punteros. Tomemos, por ejemplo, una función, llamada foo
que toma un puntero a un int:
int foo ( int * );
Aunque la persona que escribió la función foo
podría haber insertado NULL
cheques, 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 tales problemas, Cyclone introduce el tipo de puntero, que nunca puede ser . Por tanto, la versión "segura" de sería:@
NULL
foo
int foo ( int @ );
Esto le dice al compilador Cyclone que el argumento foo
nunca debería ser NULL
, evitando el comportamiento indefinido mencionado anteriormente. El simple cambio de *
a @
evita que el programador tenga que escribir NULL
cheques y que el sistema operativo tenga que NULL
capturar las desreferencias del puntero. Este límite adicional, sin embargo, puede ser un gran obstáculo para la mayoría de los programadores de C, que están acostumbrados a poder manipular sus punteros directamente con aritmética. Si bien esto es deseable, puede provocar desbordamientos de búfer y otros errores de tipo "uno a uno". Para evitar esto, el ?
tipo de puntero está delimitado por un límite conocido, el tamaño de la matriz. Aunque esto agrega sobrecarga debido a la información adicional almacenada sobre el puntero, mejora la seguridad y la protección. Tomemos, por ejemplo, una función simple (e ingenua) strlen
, escrita en C:
int strlen ( const char * s ) { int iter = 0 ; si ( s == NULL ) devuelve 0 ; while ( s [ iter ] ! = '\ 0' ) { iter ++ ; } return iter ; }
Esta función asume que la cadena que se pasa es terminada por NULL ( '\0'
). Sin embargo, ¿qué pasaría si char buf[6] = {'h','e','l','l','o','!'};
se pasara a esta cadena? Esto es perfectamente legal en C, pero haría strlen
que se repitiera la memoria no necesariamente asociada con la cadena s
. Existen funciones, tales como strnlen
los que se pueden utilizar para evitar este tipo de problemas, pero estas funciones no son estándar con cada aplicación de la norma ANSI C . La versión Cyclone de strlen
no es tan diferente de la versión C:
int strlen ( const char ? s ) { int iter , n = s . tamaño ; si ( s == NULL ) devuelve 0 ; for ( iter = 0 ; iter < n ; iter ++ , s ++ ) { if ( * s == '\ 0' ) return iter ; } return n ; }
Aquí, se strlen
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 envía automáticamente las matrices y cadenas . (Colada de ?
que *
invoca una comprobación de límites , y la fundición de ?
al @
invoca tanto una NULL
retención y una grada comprobar Colada de. *
A ?
los resultados en ninguna comprobación en absoluto; la resultante ?
puntero tiene un tamaño de 1.)
Punteros colgantes y análisis de regiones
Considere el siguiente código, en C:
char * itoa ( int i ) { char buf [ 20 ]; sprintf ( buf , "% d" , i ); return buf ; }
La función itoa
asigna una matriz de caracteres buf
en la pila y devuelve un puntero al inicio de buf
. Sin embargo, la memoria utilizada en la pila para buf
se desasigna cuando la función regresa, por lo que el valor devuelto no se puede usar de forma segura fuera de la función. Si bien gcc 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 ; return z ; }
gcc puede producir advertencias para dicho código como un efecto secundario de la opción -O2 o -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 se devuelve en esta versión de itoa
. Todas las variables locales de un ámbito determinado se consideran parte de la misma región, separadas del montón o de cualquier otra región local. Por lo tanto, al analizar itoa
, el compilador Cyclone vería que z
es un puntero a la pila local y reportaría un error.
Ver también
Referencias
- Manual de usuario de Cyclone
- Cyclone: a Type-safe Dialect of C por Dan Grossman, Michael Hicks, Trevor Jim y Greg Morrisett - publicado en enero de 2005
enlaces externos
- Página de inicio de Cyclone
- Sitio web antiguo ya que el sitio web oficial no está disponible.
- Cyclone: repositorios de código fuente
- Ciclón - Preguntas frecuentes
- Ciclón para programadores en C
Presentaciones: