Electronic – Help fix or ignore aliasing warning in gcc

arm7compiler

I'm having a problem working with the TI/Stellaris EK-LM3S6965 demo board and associated software, specifically the OLED display driver. My problem is not that it doesn't work, it's that it mostly works. Except for this one section:

//
// 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

which causes gcc to complain:

rit128x96x4.c:438: warning:
dereferencing type-punned pointer will
break strict-aliasing rules.

The problem occurs because g_pucBuffer is declared as a character array:

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

but we're accessing it as a long (32-bit, 4 characters) and so clearing the array in 2 lines of code instead of 8. The uC is a 32-bit processor, so it should do this in 2 cycles after setup. It actually uses 4 instructions, instead of the possible 1 store-multiple instruction in 2 cycles, but at this point I'm more than happy with the compiler's performance (It's a fairly new architecture, and the compiler's only a few months old).

But, when I write each byte sequentially to 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;

it does each write as a single instruction. I know, it's 4 cycles, but I want to do this right, and I think I have a clever and safe piece of code. It's more a personal issue now. I've got full optimization turned on, but it can't figure out that I really just want this 64 bits to be 0 as simply as possible.

However, what the warning wants me to do is access the variables as characters, because I'm crossing byte boundaries (Writing g_pucBuffer[0, 1, 2, and 3] in a single step). I know that they're dword aligned, I know that the code works in the original, but I want the warning to go away.

How can I either cause gcc to ignore this specific cast/aliasing issue, or do it properly?

Best Answer

Can you instead declare your variable as a union of a byte array and a long array?

I don't know if this is any more "legal" than your original code without a careful reading of the spec but it might be worth looking into.