En informática , el aliasing describe una situación en la que se puede acceder a una ubicación de datos en la memoria a través de diferentes nombres simbólicos en el programa. Por lo tanto, modificar los datos a través de un nombre modifica implícitamente los valores asociados con todos los nombres alias, lo que puede no ser esperado por el programador. Como resultado, el aliasing hace que sea particularmente difícil comprender, analizar y optimizar los programas. Los analizadores de aliasing tienen como objetivo generar y calcular información útil para comprender el aliasing en los programas.
Los alias pueden aparecer en cualquier lenguaje que pueda hacer referencia a una ubicación en la memoria con más de un nombre (por ejemplo, con punteros ). Este es un problema común con las funciones que aceptan argumentos de puntero, y su tolerancia (o la falta de ella) para los alias debe documentarse cuidadosamente, en particular para las funciones que realizan manipulaciones complejas en las áreas de memoria que se les pasan.
En algunos casos, puede ser deseable un comportamiento de alias controlado (es decir, un comportamiento de alias que se especifica, a diferencia del que permite la distribución de la memoria en C). Es una práctica común en Fortran . El lenguaje de programación Perl especifica, en algunas construcciones, el comportamiento de alias, como en los bucles. Esto permite modificar ciertas estructuras de datos directamente con menos código. Por ejemplo,foreach
mi @array = ( 1 , 2 , 3 ); foreach my $element ( @array ) { # Incrementa $element, modificando así automáticamente # @array, ya que $element está ''aliasado'' # para cada uno de los elementos de @array a su vez. $element ++ ; } imprimir "@array \n" ;
Como resultado, se imprimirá "2 3 4". Si se desea evitar los efectos de alias, se puede copiar el contenido de la variable de índice en otra y modificar la copia.
Los optimizadores a menudo tienen que hacer suposiciones conservadoras sobre las variables cuando es posible el alias. Por ejemplo, conocer el valor de una variable (como x
es 5) normalmente permite ciertas optimizaciones (como la propagación de constantes ). Sin embargo, el compilador no puede usar esta información después de una asignación a otra variable (por ejemplo, en C, *y = 10
) porque podría ser que *y
es un alias de x
. Este podría ser el caso después de una asignación como y = &x
. Como efecto de esta asignación a *y
, el valor de x
también cambiaría, por lo que propagar la información que x
es 5 a las declaraciones siguientes *y = 10
sería potencialmente incorrecto (si *y
es de hecho un alias de x
). Sin embargo, si hay información sobre punteros, el proceso de propagación constante podría realizar una consulta como: ¿puede x
ser un alias de *y
? Entonces, si la respuesta es no, x = 5
se puede propagar de forma segura.
Otra optimización afectada por el alias es la reordenación del código. Si el compilador decide que x
no tiene alias *y
, entonces el código que usa o cambia el valor de x
se puede mover antes de la asignación *y = 10
, si esto mejora la programación o permite que se realicen más optimizaciones de bucle .
Para permitir tales optimizaciones de una manera predecible, el estándar ISO para el lenguaje de programación C (incluyendo su edición más reciente C99 , ver sección 6.5, párrafo 7) especifica que es ilegal (con algunas excepciones) acceder a la misma ubicación de memoria usando punteros de diferentes tipos. Por lo tanto, un compilador puede asumir que tales punteros no tienen alias. Esta regla, conocida como la regla de alias estricto , a veces permite aumentos impresionantes en el rendimiento, [1] pero se sabe que rompe algún código que de otro modo sería válido. Varios proyectos de software violan intencionalmente esta parte del estándar C99. Por ejemplo, Python 2.x lo hizo para implementar el conteo de referencias , [2] y requirió cambios en las estructuras de objetos básicos en Python 3 para habilitar esta optimización. El núcleo de Linux hace esto porque el alias estricto causa problemas con la optimización del código en línea. [3] En tales casos, cuando se compila con gcc , se invoca la opción -fno-strict-aliasing
para evitar optimizaciones no deseadas que podrían producir código inesperado.
El término aliasing también se utiliza para describir la situación en la que, debido a una elección de diseño de hardware o a un fallo de hardware, uno o más de los bits de dirección disponibles no se utilizan en el proceso de selección de memoria. [4] Esto puede ser una decisión de diseño si hay más bits de dirección disponibles de los necesarios para soportar los dispositivos de memoria instalados. En caso de fallo, uno o más bits de dirección pueden cortocircuitarse entre sí o pueden verse forzados a conectarse a tierra (lógica 0) o al voltaje de suministro (lógica 1).
En este ejemplo, suponiendo un diseño de memoria con 8 ubicaciones, se requieren solo 3 líneas de dirección (o bits , ya que 2 3 = 8). Los bits de dirección (denominados A2 a A0) se decodifican para seleccionar ubicaciones de memoria únicas de la siguiente manera, al estilo de un contador binario estándar :
A2 | A1 | A0 | Ubicación de la memoria |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
1 | 0 | 0 | 4 |
1 | 0 | 1 | 5 |
1 | 1 | 0 | 6 |
1 | 1 | 1 | 7 |
En la tabla anterior, cada una de las 8 combinaciones únicas de bits de dirección selecciona una ubicación de memoria diferente. Sin embargo, si un bit de dirección (por ejemplo, A2) se pusiera en cortocircuito a tierra, la tabla se modificaría de la siguiente manera:
A2 | A1 | A0 | Ubicación de la memoria |
---|---|---|---|
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 1 |
0 | 1 | 0 | 2 |
0 | 1 | 1 | 3 |
En este caso, como A2 siempre es cero, las primeras cuatro posiciones de memoria se duplican y aparecen nuevamente como las segundas cuatro. Las posiciones de memoria 4 a 7 se han vuelto inaccesibles.
Si este cambio se produjera en un bit de dirección diferente, los resultados de la decodificación serían diferentes, pero en general el efecto sería el mismo: la pérdida de un solo bit de dirección reduce el espacio de memoria disponible a la mitad, con la consiguiente duplicación (aliasing) del espacio restante.