2011-08-15 11 views
13

¿Invoca el código siguiente comportamiento no definido (debido a una violación de aliasing o de otro modo)?Aliasing del puntero de matriz: ¿comportamiento indefinido?

int foo(int (*a)[10], int (*b)[5]) 
{ 
    (*a)[5]++; 
    return (*b)[0]; 
} 

int x[10]; 
foo(&x, (int (*)[5])&x[5]); 

Tenga en cuenta que el código correspondiente usando lisos tipos int * en lugar de un triple a matriz sería perfectamente legal, porque a y b habría punteros al mismo tipo y por lo tanto permite a alias entre sí.

Editar: La consecuencia interesante, si esto es de hecho una violación aliasing, es que parece ser una forma hacker pero válida para obtener restrict semántica pre-C99. Como en:

void some_func(int *aa, int *bb) 
{ 
    int (*a)[1] = (void *)aa; 
    int (*b)[2] = (void *)bb; 
    /* Now **a and **b can be assumed by the compiler not to alias */ 
} 

Es de suponer que si necesita acceder a una gran variedad real en cada dirección, se puede usar SIZE_MAX-1 y SIZE_MAX-2, etc., como los tamaños diferentes.

+1

Son punteros del mismo tipo, no se puede suponer que no alias. –

Respuesta

4

No ha accedido objetos a través de punteros de tipo diferente aquí: usted no está manipulando los objetos de matriz a la que a y b punto de sí mismos, pero los objetos apuntado por (*a)+5 y (*b)+0, a saber *((*a)+5) y *((*b)+0). Como estos son indicadores del mismo tipo, pueden alias al mismo objeto.

La asignación implícita por el operador ++ es una asignación válida para el objeto apuntado por (*b)+0: ++ es equivalente a x = x + 1 (además de x se evalúa sólo una vez) y para la asignación sencilla = el estándar dice

Si el valor almacenado en un objeto se lee desde otro objeto que se superpone de alguna manera con el almacenamiento del primer objeto, entonces el solapamiento será exacto y los dos objetos tendrán versiones calificadas o no calificadas de un t compatible. ype; de lo contrario, el comportamiento es indefinido.

Los tipos aquí son exactamente iguales y la superposición es exacta.

+0

+1 Muy interesante. Sin embargo, todavía odio todo este asunto de la semántica de los indicadores ... –

+0

Por esta lógica, ¿no sería válido acceder a 'int [5] [5]' y una superposición 'int [25]' también ...? –

+0

@R .. sí, creo que sería válido. Las matrices están de alguna manera en una zona gris. Para una 'struct' está claro que al acceder a un campo' toto.x' accede al objeto como un todo, 'A [24]' y 'B [4] [4]' se definen mediante aritmética de puntero y, por lo tanto, nunca acceden al conjunto como un todo. –

Cuestiones relacionadas