我最近遇到了一个只在中断处理程序中被修改的变量的问题。变量本身并未声明为volatile,因此在更高的优化级别下,编译器会破坏代码。但是,编译器足够聪明,可以编译中断代码,因为中断仍然会触发。
所以这是我的问题:
如果编译器足够聪明以编译中断代码,为什么它不够聪明才能意识到变量在该中断内被更改?
在更高的优化级别,未调用的函数会被优化掉。由于没有代码调用中断处理程序,因此它应该被优化掉。什么原因导致编译器编译中断代码?
答案 0 :(得分:5)
语言执行模型表示普通(非易失性)变量不能被“外力”改变。即如果您的代码流没有显式更改变量,那么从该代码流的角度来看,变量不可能发生变化。 (除了C11为多线程执行定义的内容)。您必须手动“指定”可由中断处理程序更改的变量。
这是实现C代码高效优化的主要因素之一。如果不对C程序的性能产生显着的负面影响,就无法消除它。
首先,编译器通常不会通过外部链接优化掉函数。你的中断处理程序是用外部链接声明的吗?
其次,优化函数或保留函数的决定并不是基于函数是否调用。它取决于程序中相应的符号是否以引用以任何方式。删除未引用的符号,同时保留引用的符号。除了调用它之外,还有其他方法可以引用函数符号。例如,获取函数的地址也算作对函数符号的引用。地址在程序中任何位置的函数永远不会被优化掉。
您的中断向量条目会在程序启动时以某种方式初始化,这通常涉及获取处理函数的地址。这已足以保护此功能不被优化。