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?