c++ - 什么是 (void (*) (void))((uint32_t)&__STACK_END)?

标签 c++ c syntax interrupt

这是一些带有中断 vector 的启动文件摘录。

#pragma DATA_SECTION(interruptVectors, ".intvects")
void (* const interruptVectors[])(void) =
{
  (void (*) (void))((uint32_t)&__STACK_END),
  resetISR,
  nmi_ISR,
  fault_ISR,
  ... /* More interrupt vectors */

void (* const interruptVectors[])(void) - 是必须包含函数名的函数指针数组,但我无法理解 (void (*) ( void))((uint32_t)&__STACK_END) 语法。

(void (*) (void)) 看起来像一个指向函数的指针,它什么都不返回,没有参数,也没有任何名称。有可能吗?

(uint32_t)&__STACK_END 是一个指针。还有为什么函数指针和指针放在一起?

最佳答案

这看起来像 ARM 处理器或类似处理器的中断 vector 表。中断 vector 表包含中断处理程序的地址,因此它本质上是一个函数指针数组。

该表的第一项是堆栈指针的初始化值。显然不是函数指针,而是数据指针,所以需要进行一些类型转换。不是因为处理器关心类型,而是因为 C 关心。

所以 &__STACK_END 可能是某种指针类型,它指向堆栈末尾的数据地址。然后将其转换为普通的 32 位数字,最后转换为函数指针。

如果编译器支持将其作为扩展,则可以跳过第一次转换为 uint32_t 并直接从数据指针转换为函数指针。但严格来说,在 C 标准中,从数据指针直接转换为函数指针是不合法的,必须强制转换为整数。

还有其他实现定义的问题程序员必须考虑这种转换工作:类型和对齐的大小必须兼容,不能有陷阱表示等。这在使用接近的代码时都是正常的硬件。

关于c++ - 什么是 (void (*) (void))((uint32_t)&__STACK_END)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72786319/

相关文章:

c++ - 我可以使用 select 来组合 stdin 和 Accept 吗?

c - 将数据移入和移出文件 X 位的最佳方法是什么?

Jquery 选择器 + 语法

c++ - 箭头与点语法?

c++ - 如何检查 TLB 文件中的原始 COM 定义?

c++ - 使用清晰的代码行异步调用插槽,无需连接到它

c - 如何给另一个指针赋值

python - 在 Python 中 append 到列表的美学方式?

c++ - pwrite 和 pread 比 fwrite 和 fread 有什么优势?

在 C++11 中调用 C 函数时,我可以将 std::vector 作为 FILE* 潜入吗?