2011-09-07 10 views
8

Tengo función que recibe un vector de punteros de este modo:cómo contar una C o un compilador de C++ que los punteros no son alias

void foo(int *ptrs[], int num, int size) 
{ 
    /* The body is an example only */ 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < num-1; ++j) 
     ptrs[num-1][i] += ptrs[j][i]; 
    } 
} 

Lo que yo quiero transmitir al compilador es que los punteros ptrs[i] son no alias uno del otro y que las matrices ptrs[i] no se superponen. ¿Cómo voy a hacer esto? Mi segundo motivo es fomentar la vectorización automática.

Además, ¿hay alguna manera de obtener el mismo efecto que __restrict__ en un iterador de std::vector?

+1

Nota importante: El estándar C++ NO admite el calificador 'restrict' de C99 - no es incluso una palabra clave Así que cualquier uso de 'restrict' en un programa C++ se basa en una extensión de implementación –

Respuesta

9

restrict, a diferencia de los más comunes const, es una propiedad del puntero en lugar de los datos apuntaban a . Por lo tanto, pertenece al lado del lado derecho del modificador del declarador '*'. [] en una declaración de parámetro es otra manera de escribir *. Poner estas cosas juntas, debe ser capaz de obtener el efecto deseado con esta función prototipo:

void foo(int *restrict *restrict ptrs, int num, int size) 
{ 
    /* body */ 
} 

y sin necesidad de nuevos nombres. (No probado. Su millaje puede variar. restrict es una sugerencia de optimización pura y puede que en realidad no haga nada constructivo con su compilador.)

+2

A menos que esté equivocado, una de esas declaraciones de "restricción" es superflua; no hay otras variables de tipo "int **" con las que se pueda producir un aliasing. "int * restrict * ptrs" debería hacer el trabajo. Y me pregunto si "int * restringe ptrs []" podría hacerlo también ... – davmac

+0

En mi humilde opinión, ambos 'restrict's son necesarios, ya que otros punteros podrían existir fuera del alcance de 'foo'. –

+0

"Lo que quiero transmitir al compilador es que los punteros ...no son alias de * entre sí * " – davmac

4

En C++, se asume que los argumentos del puntero no tienen alias si apuntan a tipos fundamentalmente diferentes (reglas de "alias estricto").

En C99, la palabra clave "restringir" especifica que un argumento de puntero no alía ningún otro argumento de puntero.

+1

Bastante segura, se aplican reglas estrictas de alias en' c' y 'C++'. http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

+0

@Darren Gracias, es bueno aprender. –

+1

Sí, sí lo hacen. Además, esta respuesta no le dice al OP nada de lo que él o ella no sabía. – zwol

7

Algo así como:

void foo(int *ptrs[], int num, int size) 
{ 
    /* The body is an example only */ 
    for (int i = 0; i < size; ++i) { 
     for (int j = 0; j < num-1; ++j) { 
     int * restrict a = ptrs[num-1]; 
     int * restrict b = ptrs[j]; 
     a[i] += b[i]; 
    } 
} 

... debería hacerlo, creo que, en C99. No creo que haya ninguna forma en C++, pero muchos compiladores de C++ también admiten restringir.

+0

Ah, ya veo, tengo que introducir nuevos nombres. Gracias. – san

+1

Por cierto, puede usar un truco similar para marcar la referencia del objeto por un iterador como no alias (es decir, asignar su dirección a un puntero restringido). – davmac

+1

Tienes los calificadores '' restring'' en el lado equivocado de los '' * 'aquí. – zwol

Cuestiones relacionadas