有安全或任务关键型的嵌入式系统,硬实时的嵌入式系统,以及两者兼而有之的嵌入式系统。
硬实时的嵌入式系统可能会受到约束,也可能不受约束。同事们在 70 年代研究了一个导弹制导系统,该系统在其主循环中有大约 4 条指令的净空!(您可以想象,它是用汇编程序编写的,并且使用了经过调整的执行程序,而不是 RTOS。不支持异常)。另一方面,我在 1 GHz PowerPC 板上工作的最后一个,对特定中断的响应有 2 毫秒的截止时间,我们测量的最坏情况是 1.3 毫秒(无论如何这是一个软实时要求,您不必连续错过太多)。
该系统也有安全要求(我知道,我知道,安全导弹系统,呵呵),虽然我们被允许使用异常,但未处理的异常意味着必须关闭系统,无论导弹是否在飞行,导致损失导弹。而且我们被严格禁止说when others => null;
吞下异常,所以我们没有处理的任何异常都将被“未处理”并反弹到顶层。
论据是,如果发生未处理的异常,您将无法再知道系统的状态,因此您无法证明继续。当然,更广泛的安全工程必须考虑整个系统应该采取什么行动(例如,也许这个处理器应该在恢复模式下重新启动)。
有时人们使用异常作为他们控制流的一部分;实际上,对于处理随机文本输入,一种常用的方法是,而不是检查文件结尾,而是继续进行,直到你得到一个End_Error
;
loop
begin
-- read input
-- process input
exception
when End_Error => exit;
end;
end loop;
雅各布的回答讨论了使用 SPARK。您不必使用 SPARK 来不处理异常,尽管能够向您自己(和您的安全审计员!)证明不会有任何异常当然会很好。处理异常非常棘手,一些 RTS(例如Cortex GNAT RTS)不这样做;配置编译指示
pragma Restrictions (No_Exception_Propagation);
意味着异常不能传播到引发它们的范围之外(程序将因调用 a 而崩溃Last_Chance_Handler
)。
仅在引发异常的范围内传播异常并不是,IMO,有用:
begin
-- do something
if some error condition then
raise Err;
end if;
-- do more
exception
when Err =>
null;
end;
避免“做更多”代码是一种相当混乱的方式。最好使用标签!