【发布时间】:2015-02-26 09:49:01
【问题描述】:
我正在用 C11 编写引导加载程序。当引导加载程序需要将控制权转移给固件时,它会读取位于预定义内存地址的函数指针并调用它。代码如下所示:
typedef void (FirmwareBootFn)(void);
typedef struct
{
uint32_t stackPointer;
FirmwareBootFn* programCounter;
}
FirmwareBootControl;
static FirmwareBootControl g_bootControl __attribute__ ((section (".boot_control")));
void
Firmware_boot( void )
{
setStackPointer( g_bootControl.stackPointer );
g_bootControl.programCounter();
}
函数Firmware_boot() 永远不会返回,因此将其声明为noreturn 是有意义的:
#include <stdnoreturn.h>
noreturn void
Firmware_boot( void );
但我还需要将FirmwareBootFn 声明为noreturn,以避免编译器抱怨Firmware_boot() 可能会返回。
我尝试了(可能)noreturn 在typedef 中的所有排列,但没有任何结果。我也知道该属性不能在typedef 中设置,因为它不是类型的一部分。
有没有办法将我的Firmware_boot() 标记为noreturn 以避免警告(以及没有警告抑制作弊:-))?
【问题讨论】:
-
我刚刚找到了 gcc 的解决方法:使用 **__builtin_unreachable**() 将代码的特定点标记为“永远不会执行此行”,从而授予 noreturn 属性。尽管这样有效,但它不是可移植的,并且不允许编译器理解(至少在 IMO)g_bootControl.programCounter() 不会返回并应用适当的优化。
-
@MaxP,一个小型测试程序的文档和汇编输出似乎都表明它用于优化。 (如果
foo被声明为_Noreturn而bar不是,foo();和bar(); __builtin_unreachable();生成等效代码。) -
如果您愿意使用扩展程序,请使用
attribute。请看我的回答。