Search code examples
cpointerscompiler-constructionpicpic32

PIC32 dereferencing pointers possible compiler bug


I am working on some code for the PIC32MX795F512L using the XC32 compiler. I need to read data out of a buffer passed to a function as a void*. I need to read the data as an array of unsigned 32 bit integers. the problem is when I cast the void* to a uint32* and try to read a value at index 0 of that array, the general error handler gets called by the processor, while if I cast the void* to a uint8* and do some bit manipulation to get the same data, it works properly.

the code looks like this:

void foo(void* data, uint32 length)
{
    uint32 i,j;
    uint32 block;
    for(i = 0, j = 0; i < length; i+= sizeof(uint32),j++)
    {
        printfUART(DEBUG_UART,"Debug 0\r\n");
#if 0//working code
        block = ((uint8*)data)[i + 3];
        block <<= 8;
        block |= ((uint8*)data)[i + 2];
        block <<= 8;
        block |= ((uint8*)data)[i + 1];
        block <<= 8;
        block |= ((uint8*)data)[i + 0];
#else//not working code
        block = ((uint32*)data)[j];
#endif
        printfUART(DEBUG_UART,"Debug 1\r\n");
    }
}

if you change the #if 0 to #if 1 the code works as expected and I see "Debug 0" and "Debug 1" printed many times in the loop.

but if you leave it as is, "Debug 0" prints only once, and then the code jumps out of the loop into the cpu general error handler set by the compiler. Is this a bug in the XC32 ompiler, or is there something im missing?


Solution

  • I think this is an alignment problem.

    If data is not at an even address (e.g. because it is in fact an array of bytes), accessing it 32bit-wise could be not possible on your platform.

    The C standard (ISO/IEC 9899:1999, 6.3.2.3) says:

    A pointer to an object or incomplete type may be converted to a pointer to a different object or incomplete type. If the resulting pointer is not correctly aligned for the pointed-to type, the behavior is undefined.