Looking at the code for heap 1 in FreeRTOS...
#if ( configAPPLICATION_ALLOCATED_HEAP == 1 )
/* The application writer has already defined the array used for the RTOS
* heap - probably so it can be placed in a special segment or address. */
extern uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#else
static uint8_t ucHeap[ configTOTAL_HEAP_SIZE ];
#endif /* configAPPLICATION_ALLOCATED_HEAP */
...we see that a heap is just an array of uint8_t objects.
But then, in its void* pvPortMalloc(size_t xWantedSize)
function, it defines a uint8_t*
called pucAlignedHeap
, and a size_t
called xNextFreeByte
.
Our return value pvReturn
is then defined in this block...
/* Check there is enough room left for the allocation and. */
if( ( xWantedSize > 0 ) && /* valid size */
( ( xNextFreeByte + xWantedSize ) < configADJUSTED_HEAP_SIZE ) &&
( ( xNextFreeByte + xWantedSize ) > xNextFreeByte ) ) /* Check for overflow. */
{
/* Return the next free byte then increment the index past this
* block. */
pvReturn = pucAlignedHeap + xNextFreeByte;
xNextFreeByte += xWantedSize;
}
...and is then expected to be used by the programmer to store whatever data they want:
//Some example:
my_struct* x = pvPortMalloc(sizeof(my_struct));
But since the underlying data type is an array of uint8_t
, doesn't that mean that any real usage of the heap violates C's aliasing requirements?
And if that's true, then why are they allowed to violate these requirements without worrying about UB? FreeRTOS is hardly a small hobby project, so they must know what they're doing, and yet it surely looks like this is UB. Why can they do this, but I can't? They do not appear to have -fno-strict-aliasing
defined, so I don't think it's that.