0
votes

I have little dilemma with my code.

I have function which returns pointer (uint8_t*) to data buffer. Is it possible and legal to cast this pointer to uint16_t when I need 2 values from array as uint16_t? Or there will be problem with aligning? Buffer is filled via byte reading from I2C.

The problem exists on MCU but when I try this with visualstudio, it´s ok. MCU - Hardfault

uint8_t arr[8];

uint8_t * FuncReturnPointer(void)
{
     arr[0] = 0xEE;
     arr[1] = 0xFF;

     return arr;
}

main
{
     uint16_t val16 = 0;

     val16 = *(uint16_t*)FuncReturnPointer();
}

Is there something wrong/dangerous?

1
Strictly speaking - no, it is not legal because of strict aliasing. It could be legal in some cases if the original pointer is char* and alignment requirements are satisfied. The general advice would be to "manually" compose the resulting uint16_t such as (arr[1] << 8) + arr[0] to avoid this and possible endianess issues.Eugene Sh.
Thanks for the reply I thought so, that there will be problem.Wojtkingson
Also it ought to be int main(void) at least ....alk
@alk arr is global.Eugene Sh.

1 Answers

0
votes

There are two separate issues here:

  • strict aliasing violation
  • possible alignment violation

Either of these can lead to various "interesting" phenomena. I could bet that this is due to alignment violation, i.e. arr does not happen to reside at an address divisible by _Alignof(uint16_t). The proper fix is to use either

  • arithmetic:

    val16 = ((uint16_t)*address << 8) | (address);
    
  • memcpy:

    memcpy(&val16, address, sizeof (val16));