在中断处理程序中使用C块作用域?
在函数中或在中断处理程序中使用C块作用域有什么优点或缺点 从链接--参考堆栈使用情况 通常,您可以通过以下方式降低程序的堆栈要求:在中断处理程序中使用C块作用域?,c,arm,embedded,cpu,C,Arm,Embedded,Cpu,在函数中或在中断处理程序中使用C块作用域有什么优点或缺点 从链接--参考堆栈使用情况 通常,您可以通过以下方式降低程序的堆栈要求: 编写只需要少量变量的小函数 避免使用大型局部结构或阵列 例如,通过使用替代算法来避免递归 最小化函数中每个点在任何给定时间使用的变量数量 使用C块作用域并仅在需要时声明变量,从而重叠不同作用域使用的内存。 使用C块作用域的优点或缺点不是很清楚。如果您写: { int foo[1000]; int bar[1000]; … code that
{
int foo[1000];
int bar[1000];
… code that uses foo …
… code that uses bar …
}
{
{
int foo[1000];
… code that uses foo …
}
{
int bar[1000];
… code that uses bar …
}
}
然后整个块都存在foo
和bar
,必须使用不同的内存。(编译器/优化器可能会意识到它们不是同时使用的,并安排使用相同的内存,但各种因素可能会干扰这一点,因此您不能依赖它。)
如果你写:
{
int foo[1000];
int bar[1000];
… code that uses foo …
… code that uses bar …
}
{
{
int foo[1000];
… code that uses foo …
}
{
int bar[1000];
… code that uses bar …
}
}
然后
foo
和bar
只在不同的时间存在,因此编译器可以为它们使用相同的内存。这只是意味着如果使用更多范围限制变量的生存时间,编译器可以优化函数执行所需的空间。考虑到
int x;
// [some code]
int y;
// [some code not using x]
编译器必须保持x
,直到函数结束。如果您改为这样构造它:
{
int x;
// [some code]
}
{
int y;
// [some code not using x]
}
使用y
的代码中不存在x
,因此编译器可能会重新使用先前由x
占用的相同空间(很可能编译器确实会这样做)
一般说明:如果您必须在ISR中考虑这一点,您的ISR可能已经太大了。使ISR尽可能地最小化和快速——例如,让事件排队可能是ISR的一个好操作。在C代码中使用块,使代码清晰且符合逻辑。这适用于所有的C编程,而不仅仅是中断。通常最好只在使用局部变量的范围内定义它们。(不要过火,只为变量定义新的作用域——但如果变量仅在循环或条件的分支中使用,请在该块中定义它。) 只要您使用的是优化编译器(并且启用了优化!),当您的局部变量在块内或块外时,堆栈空间和使用情况几乎没有差异。编译器将足够聪明,可以看到变量的有效生存期,并适当限制其分配
如果你没有对你的编译器进行优化,你应该这样做 这是一个非常广泛的问题,需要征求意见,因此不太适合堆栈溢出。我认为变量声明的作用域如何与编译器如何选择使用堆栈空间之间没有必要的联系。中断处理程序的总体经验法则:保持简单。ISR的总体经验法则(II):如果不需要,不要让它分配资源。在块范围内分配堆栈是一种资源分配(尽管是简单的)。如果我不得不忍受堆栈溢出,我宁愿在应用程序代码中使用它,而不是在ISR中使用它,因此我通常会在ISR中使用已分配的内存。当然,如果在ISR中在堆栈上分配K,则可能已经做了错误的事情:-)根据我的经验,编译器可以为所有函数变量创建堆栈框架,而不考虑作用域,这样在函数中,作用域只影响可见性。不是一辈子。YMMV,但我不依赖于此。从逻辑上讲,编译器需要保留x直到函数结束。但在实践中,如果启用了优化程序,它通常不会这样做-它将仅在需要时保持x。