什么是(void(*)(void))((uint32_t)& __ stack_end)?
这是一些带有中断向量的启动文件摘录。
#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
是指指针。为什么函数指针和指针在一起?
This is some startup file excerpt with interrupt vectors.
#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)
- is an array of function pointers that must contain function names, but I can't understand the (void (*) (void))((uint32_t)&__STACK_END)
syntax.
(void (*) (void))
looks like a pointer to a function that returns nothing, without arguments and doesn't have any name. Is it possible?
(uint32_t)&__STACK_END
is a pointer. And why are the function pointer and pointer together?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这看起来像是用于手臂处理器或类似的中断矢量表。中断矢量表包含中断处理程序的地址,因此本质上是功能指针的数组。
该表的第一个条目是堆栈指针的初始化值。这显然不是功能指针,而是数据指针,因此需要某种类型的转换。不是因为处理器关心类型,而是因为C确实如此。
因此,
& __ stack_end
是可以指向堆栈末端的数据地址的一些指针类型。然后将其转换为平原的32位编号,最后转换为函数指针。如果编译器将其作为扩展名支持,则可以跳过第一个铸件到
UINT32_T
,并直接从数据指针铸造为函数指针。但是严格来说,在C标准转换中,直接从数据指针转换为函数指针是不合法的,并且必须将其施加到Interger。还有其他插入定义的问题,程序员必须考虑使用此类转换以进行工作:类型和对齐方式的大小必须兼容,不得有陷阱表示等。当使用接近硬件的代码时,这都是正常的。
This looks like the interrupt vector table for an ARM processor or similar. The interrupt vector table contains the addresses of interrupt handlers, so it is essentially an array of function pointers.
The first entry of this table is the initialization value for the stack pointer. It's obviously not a function pointer, but a data pointer, so some type conversion is needed. Not because the processor cares about types, but because C does.
So
&__STACK_END
is presumable some pointer type which points to a data address at the end of the stack. This is then converted to a plain 32-bit number, and finally converted to a function pointer.It might have been possible to skip the first cast to
uint32_t
and cast directly from a data pointer to a function pointer, if the compiler supported it as an extension. But strictly speaking, in the C standard conversion from a data pointer directly to a function pointer is not legal, and cast to interger is necessary.There are also additional implemetation defined issues programmer must consider for this kind conversion to work: sizes of types and alignments must be compatible, there must not be trap representations, etc. This is all normal when working with code that is close to hardware.
a
我个人认为,有更好的方法可以更清楚地定义此问题。
The first value of the vector table of a Cortex-M is the initial value of the stack pointer, and that looks like your case. This syntax is a hack to define the whole vector table as a constant array of function pointer of type void(*function)(void) while defining the first value as the stack pointer value as a constant.
Personally I think there are better ways to define this more clearly.