kan*_*ler 3 c c++ syntax interrupt
这是一些带有中断向量的启动文件摘录。
#pragma DATA_SECTION(interruptVectors, ".intvects")
void (* const interruptVectors[])(void) =
{
(void (*) (void))((uint32_t)&__STACK_END),
resetISR,
nmi_ISR,
fault_ISR,
... /* More interrupt vectors */
Run Code Online (Sandbox Code Playgroud)
void (* const interruptVectors[])(void)- 是一个函数指针数组,必须包含函数名称,但我无法理解(void (*) (void))((uint32_t)&__STACK_END)语法。
(void (*) (void))看起来像一个指向函数的指针,该函数不返回任何内容,没有参数,也没有任何名称。是否可以?
(uint32_t)&__STACK_END是一个指针。还有为什么函数指针和指针放在一起呢?
这看起来像 ARM 处理器或类似处理器的中断向量表。中断向量表包含中断处理程序的地址,因此它本质上是一个函数指针数组。
该表的第一项是堆栈指针的初始化值。显然它不是函数指针,而是数据指针,因此需要进行一些类型转换。不是因为处理器关心类型,而是因为 C 关心类型。
因此&__STACK_END,可能有某种指针类型指向堆栈末尾的数据地址。然后将其转换为普通的 32 位数字,最后转换为函数指针。
uint32_t如果编译器支持将其作为扩展,则可能可以跳过第一次转换并直接从数据指针转换为函数指针。但严格来说,在C标准中从数据指针直接转换为函数指针是不合法的,强制转换为整数是必要的。
为了使这种转换正常工作,程序员还必须考虑其他实现定义的问题:类型和对齐的大小必须兼容,不能有陷阱表示等。在使用接近硬件的代码时,这都是正常的。