在关键任务的实时应用中安全使用C++

8

我希望听到各种意见,如何在关键任务的实时应用程序中安全地使用C++。

更准确地说,可能可以创建一些宏/模板/类库以进行安全数据操作(封闭溢出、零除产生无穷大值或仅对特殊“非零”数据类型进行除法),带有边界检查和foreach循环的数组,安全智能指针(类似于boost shared_ptr),甚至是安全的多线程/分布式模型(消息传递和轻量级进程,比如Erlang语言中定义的那些)。

然后,我们禁止一些危险的C/C++构造,例如原始指针、某些原始类型、本机“new”运算符和本机C/C++数组(当然是针对应用程序员而不是库编写者)。理想情况下,我们应该创建一个特殊的预处理器/检查器,至少必须有一些正式的检查程序,可以通过某些工具或某些人手动应用于源代码。

所以,我的问题:

1)是否存在利用这种想法的现有库/项目?(嵌入式C++显然不是所需的类型)?

2)这是个好主意还是不好的主意?或者它只对原型设计另一种假设性语言有用?或者它完全无法使用?

3)关于这个问题的任何其他想法(或链接)也欢迎。

如果这个问题实际上不是一个问题、离题、重复等,我很抱歉,但我没有找到更合适的地方来问。


2
可能直接使用Ada比将C++转换为Ada更快。 - Hans Passant
3个回答

9

如果想要了解如何编写C++用于关键任务的实时应用程序,请查看联合打击战斗机编码标准。其中许多规则都基于MISRA C编码标准,我认为这是专有的。PC-Lint是一个C++代码检查器,具有类似于您所需的规则集(包括MISRA规则)。我相信您也可以自定义自己的规则。


感谢提供参考,如果能够自定义 Lint 工具,那将是一个有趣的可能性。 - user396672

2
我们在关键任务的实时应用中使用C++,虽然我想理论上我们很容易(因为我们只需要提供与客户使用的硬件一样好的实时保证)。因此,充分的剖析让我们可以不使用mlockall()、堆栈预加载或任何其他实时传统。至于语言本身,我认为现代C++编码实践(鼓励避免C概念的实践)完全足够编写健壮的应用程序,可以在实时环境中使用,考虑到21世纪的硬件。
单元测试和QA应该是主要的工作重点,而不是内部库,这些库复制了现有的语言特性。

也许你是对的,更好地强调不存在的能力,如分布式/多线程同步和内存模型。任何 + - / * ... 的重载都不能保证由糟糕的程序员编写的错误程序 :) 也许... - user396672
@user396672:我们曾经有一些这样的特殊库,在1992年C++还不成熟时它们确实有意义,但随着标准和通用库(如boost)变得更加高效和更好理解,它们在过去几十年中变得难以维护。但是,我们的优先级继承消息传递库完全是我们自己的。 - Cubbi

1

如果你正在使用C++编写关键的高性能实时软件,那么你可能需要尽可能地利用硬件的每一微秒。因此,我不建议实现所有额外的检查,比如你提到的那些,至少是那些对程序执行有开销影响的检查。你可以明显地屏蔽浮点异常,以防止除零导致程序崩溃。

以下是一些观察:

  • 对所有代码进行同行评审(可能需要多个评审人)。这将大大提高质量,而无需进行大量的运行时检查。
  • 确保使用诊断工具和非发布版本的断言。
  • 使用模拟系统测试非嵌入式硬件。
  • C++是专门为了性能而设计的,没有像边界检查这样的东西。

总的来说,我不建议任意限制语言,虽然使用RAII和智能指针应该只会带来最小的开销,并提供良好的效益。

其他人指出,如果你想要Ada,就直接使用Ada。


智能指针,不幸的是,有开销。例如,shared_ptr使用一些中间对象来实际引用我们想要指向的对象。RAII,你是对的,几乎没有开销。 谢谢您的回答,我真的不确定需要正式限制的必要性...我问这个问题是因为我不确定 :) - user396672
@user396672 这就是为什么Stroustrup如此偏爱unique_ptr而不是shared_ptr的原因:http://www2.research.att.com/~bs/C++0xFAQ.html#std-shared_ptr - Cubbi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接