FreeRTOS 堆实现是否违反 C 别名规则?

问题描述 投票:0回答:1

查看 FreeRTOS 中堆 1 的代码...

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

...我们看到堆只是一个 uint8_t 对象的数组。

但是,在它的

void* pvPortMalloc(size_t xWantedSize)
函数中,它定义了一个名为
uint8_t*
pucAlignedHeap
,和一个名为
size_t
xNextFreeByte

我们的返回值

pvReturn
然后在这个块中定义...

 /* 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;
        }

...然后被程序员用来存储他们想要的任何数据:

//Some example:
my_struct* x = pvPortMalloc(sizeof(my_struct));

但是由于底层数据类型是

uint8_t
的数组,这是否意味着堆的任何实际使用都违反了 C 的别名要求?

如果这是真的,那为什么允许他们违反这些要求而不用担心 UB? FreeRTOS 算不上是一个小型的业余爱好项目,因此他们必须知道自己在做什么,但它看起来确实像是 UB。为什么他们可以做到这一点,而我却不能?他们似乎没有定义

-fno-strict-aliasing
,所以我不认为是那样。

c freertos strict-aliasing
1个回答
0
投票

为什么他们可以这样做,而我不能?

你可以……但它是有代价的。

C 标准定义了许多行为规则,任何符合标准的实现都必须遵守这些规则。

此外,C 标准将许多事情留给了实现。这称为实现定义的行为。引用 C 标准 20111 草案 N1570:

3.4.1 实现定义的行为 未指定的行为,其中每个实现都记录了如何做出选择

最重要的是,该标准具有未定义行为的概念。

3.4.3 未定义的行为 行为,在使用不可移植或错误的程序构造或错误数据时, 本国际标准对此没有要求

对于未定义的行为,注释说:

可能的未定义行为包括从完全忽略情况到不可预测 结果,以 在翻译或程序执行期间以文件化的方式表现 环境(有或没有诊断消息的发布),终止翻译或 执行(发布诊断消息)

现在,如果您愿意编写只能用于特定实现/平台/环境的 C 代码,您可以编写非标准兼容代码,只要目标实现定义了行为就可以正常工作。没问题。那里有很多代码可以做到这一点。

代价是您的代码不能用于任何实现。

顺便说一句:

问题中提到的具体代码使用

uint8_t
。通过这样做,代码仅限于用于支持
uint8_t
的实现。正如 N1570 的“7.20.1.1 精确宽度整数类型”中所写,C 标准并不要求所有实现都实现该类型。

© www.soinside.com 2019 - 2024. All rights reserved.