[英]What does void (* const ivt[])(void) mean?
我正在阅读 Daniele Lacamera 的《嵌入式系统架构》一书。 在第 4 章,启动代码
__attribute__ ((section(".isr_vector"))) void (* const ivt[])(void) =
{
(void (*) (void))(END_STACK),
isr_reset,
//...
};
我不明白void (* const ivt[])(void)
,是数组吗? 如果是数组, (void)
是什么意思?
安装工具 cdecl 并要求它向您解释:
mrvn@ryzen:~$ cdecl
Type `help' or `?' for help
cdecl> explain void (* const ivt[])(void)
declare ivt as array of const pointer to function (void) returning void
这是微控制器中断向量表的声明,可能是 ARM Cortex M。
__attribute__ ((section(".isr_vector")))
是一个非标准的 gcc 扩展,将变量分配给内存中的特定部分(绝对地址)。 您将在相应的链接描述文件中找到.isr_vector
。void (* const ivt[])(void)
:
void (*f)(void)
将创建一个函数指针(指向一个不带参数且不返回值的函数 - 这对于所有中断服务例程都是如此)。void (*f[])(void)
将创建一个函数指针数组。 由于未指定数组的大小,因此大小将由以下初始值设定项列表确定。void (* const ivt[])(void)
添加const
关键字将使函数指针数组只读,这是一个要求,因为它应该在闪存中分配并且在运行时永远不会更改。(void (*) (void))(END_STACK)
可以将整数END_STACK
转换为函数指针。 或者,这也可能是从结构或其他对象到函数指针的脏的、严格来说无效的强制转换。 目标似乎是一个 ARM 内核,其中默认堆栈指针存储在中断向量表的底部,然后 sp 由硬件自动设置。isr_reset
是第一个中断,复位向量。它是一个名为ivt
的数组,包含指向不带参数并返回void
的函数的常量指针。
我不理解 void (* const ivt[])(void),它是数组吗?
是的, ivt
是一个指向函数的常量指针数组,它不接受任何参数并且不返回任何内容。
ivt
数组的元素类型是
void (* const)(void)
这意味着指向函数的常量指针,它不接受任何参数并且不返回任何内容。
如果是数组, (void) 是什么意思?
这意味着函数不接受任何参数。
ivt
是一个常量指针数组,指向不带参数且返回类型为void
的函数。
也许一个例子可能有助于更好地理解这种情况:
void func1()
{
std::cout<<"func1 called"<<std::endl;
}
void func2()
{
std::cout<<"func2 called"<<std::endl;
}
void foo()
{
std::cout<<"foo called"<<std::endl;
}
void foobar()
{
}
int main()
{
//----------------vvv---------------------------------> ivt is an array of const pointers to a function with return type of void and having 0 parameters
void (* const ivt[])(void) = {func1, func2, foo};
//--------------------------------^^^^^--^^^^^--^^^---> add pointers to these 3 functions into the array
//iterate through the elements in the array and call the member functinos
for(void (*const PTR)(void): ivt)
{
PTR();
//-----------v---------------------------------------->this assignment won't work because pointers are themselves const so you can make them point to another function
//PTR = foobar;
}
}
上述程序的输出是:
func1 called
func2 called
foo called
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.