2 votos

Ayuda para arreglar o ignorar la advertencia de aliasing en gcc

Estoy teniendo un problema al trabajar con la placa de demostración TI/Stellaris EK-LM3S6965 y el software asociado, específicamente el controlador de la pantalla OLED. Mi problema no es que no funcione, es que sobre todo obras. Excepto por esta sección:

//
// Clear out the buffer used for sending bytes to the display.
//
*(unsigned long *)&g_pucBuffer[0] = 0;  //Line 438
*(unsigned long *)&g_pucBuffer[4] = 0;  //Line 439

lo que hace que gcc se queje:

rit128x96x4.c:438: advertencia: la desreferenciación de un puntero de tipo puntuado romperá las reglas de aliasing estricto.

El problema se produce porque g_pucBuffer se declara como una matriz de caracteres:

//*****************************************************************************
//
// Buffer for storing sequences of command and data for the display.
//
//*****************************************************************************
static unsigned char g_pucBuffer[8];

pero estamos accediendo a él como un long (32 bits, 4 caracteres) y por lo tanto limpiando el array en 2 líneas de código en lugar de 8. El uC es un procesador de 32 bits, por lo que debería hacer esto en 2 ciclos después de la configuración. En realidad utiliza 4 instrucciones, en lugar de la posible instrucción store-multiple en 2 ciclos, pero en este punto estoy más que contento con el rendimiento del compilador (Es una arquitectura bastante nueva, y el compilador sólo tiene unos meses).

Pero, cuando escribo cada byte secuencialmente a 0,

g_pucBuffer[0] = 0;
g_pucBuffer[1] = 0;
g_pucBuffer[2] = 0;
g_pucBuffer[3] = 0;
g_pucBuffer[4] = 0;
g_pucBuffer[5] = 0;
g_pucBuffer[6] = 0;
g_pucBuffer[7] = 0;

hace cada escritura como una sola instrucción. Lo sé, son 4 ciclos, pero quiero hacerlo bien, y creo que tengo un trozo de código inteligente y seguro. Ahora es más una cuestión personal. Tengo la optimización completa activada, pero no puede entender que realmente sólo quiero que estos 64 bits sean 0 de la manera más sencilla posible.

Sin embargo, lo que la advertencia quiere que haga es acceder a las variables como caracteres, porque estoy cruzando los límites de los bytes (escribiendo g_pucBuffer[0, 1, 2 y 3] en un solo paso). Sé que están alineados con dwords, sé que el código funciona en el original, pero quiero que la advertencia desaparezca.

¿Cómo puedo hacer que gcc ignore este problema específico de cast/aliasing, o que lo haga correctamente?

5voto

SQLMenace Puntos 68670

Un cast intermedio a (void *), y luego cast a (long *) puede deshacerse de la advertencia. Lo he comprobado hoy mismo (al menos con gcc 3.4.5), que

*(long*)(void*)&buffer[0] = 0;

despoja al compilador de la noción de que el cielo se caerá si lanzas &buffer[0] a (long *).

Yo diría que esto es mejor que usar la opción -fno-strict-aliasing, ya que -fno-strict-aliasing tendrá un efecto global, mientras que el reparto intermedio puede usarse caso por caso, y es explícitamente obvio en tu fuente actual donde has tratado el problema.

4voto

Joseph Puntos 786

¿Puede declarar su variable como una unión de una matriz de bytes y una matriz de longitudes?

No sé si esto es más "legal" que su código original sin una lectura cuidadosa de la especificación, pero podría valer la pena mirar.

3voto

Personalmente creo que las advertencias del compilador están ahí por una razón. Desactivarlas o ignorarlas (como parecen defender algunas de las otras respuestas) es una mala idea. -fno-strict-aliasing impide un montón de otras optimizaciones, al final, probablemente perderás mucho más rendimiento que los 4 ciclos que ahorras haciendo el hack de código C.

2voto

Shane Arney Puntos 2775

¿No funcionaría -fno-strict-aliasing?

1voto

letronje Puntos 128

Respuesta rápida: elimine -Werror de su Makefile. Sólo con esta opción activada la advertencia será tratada como un error.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X