为什么不建议在 space/radiated 环境中使用 C++ 模板?
Why is C++ template use not recommended in a space/radiated environment?
通过阅读 ,我明白了,例如,为什么在辐射高的环境中不推荐动态分配或异常,例如在 space 或核电站中。
关于模板,我不明白为什么。你能给我解释一下吗?
考虑到this answer,据说用起来很安全
注意:我说的不是复杂的标准库内容,而是特制的自定义模板。
注意 space-compatible(radiation-hardened, aeronautics compliant) computing devices are very expensive (including to launch in space, since their weight exceeds kilograms), and that a single space mission costs perhaps hundred million € or US$. Losing the mission because of software or computer concerns has generally a prohibitive cost so is unacceptable and justifies costly development methods and procedures that you won't even dream using for developing your mobile phone applet, and using probabilistic reasoning and engineering approaches is recommended, since cosmic rays are still somehow an "unusual" event. From a high-level point of view, a cosmic ray and the bit flip it produces can be considered as noise in some abstract form of signal or of input. You could look at that "random bit-flip" problem as a signal-to-noise ratio problem, then randomized algorithms may provide a useful conceptual framework (notably at the meta level, that is when analyzing your safety-critical source code or compiled binary, but also, at critical system run-time, in some sophisticated kernel or thread scheduler), with an information theory 观点。
Why C++ template use is not recommended in space/radiated environment?
该建议是对 MISRA C coding rules and of Embedded C++ rules, and of DO178C recommendations, and it is not related to radiation, but to embedded systems. Because of radiation and vibration constraints, the embedded hardware of any space rocket computer has to be very small (e.g. for economical and energy-consumption reasons, it is more -in computer power- a Raspberry Pi-like system than a big x86 server system). Space hardened chips cost 1000x much as their civilian counterparts. And computing the WCET on space-embedded computers is still a technical challenge (e.g. because of CPU cache related issues). Hence, heap allocation is frowned upon in safety-critical 嵌入式 software-intensive 系统的 泛化 ,C++(您将如何处理 out-of-memory 这些条件?或者你如何 证明 你有足够的 RAM 用于 所有 真实的 运行 时间案例?)
记得在安全-critical software world, you not only somehow "guarantee" or "promise", and certainly assess (often with some clever probabilistic reasoning), the quality of your own software, but also of all the software tools used to build it (in particular: your compiler and your linker; Boeing or Airbus won't change their version of GCC cross-compiler used to compile their flight control software without prior written approval from e.g. FAA or DGAC)。您的大多数软件工具都需要以某种方式获得批准或认证。
请注意,实际上,大多数 C++(但肯定不是全部)模板在内部使用堆。和标准 C++ containers certainly do. Writing templates which never use the heap is a difficult exercise. If you are capable of that, you can use templates safely (assuming you do trust your C++ compiler and its template expansion machinery, which is the trickiest part of the C++ front-end of most recent C++ compilers, such as GCC or Clang).
我猜出于类似的(工具集可靠性)原因,使用许多 source code generation tools (doing some kind of metaprogramming, e.g. emitting C++ or C code). Observe, for example, that if you use bison
(or RPCGEN) in some safety critical software (compiled by make
and gcc
), you need to assess (and perhaps exhaustively test) not only gcc
and make
, but also bison
. This is an engineering reason, not a scientific one. Notice that some embedded systems may use randomized algorithms, in particular to cleverly deal with noisy 输入信号(甚至可能由于 rare-enough 宇宙射线而随机位翻转)是不受欢迎的。证明、测试或分析(或只是评估)此类 random-based 算法是一个相当困难的话题。
另请查看 Frama-Clang and CompCert 并观察以下内容:
C++11(或以下)是一种极其复杂的编程语言。它没有完整的formal semantics。人民
足够精通 C++ 的人在全世界只有几十人(可能是大多数
其中的一部分在其标准委员会中)。我有能力编码
C++,但没有解释 move 的所有微妙的极端情况
语义,或 C++ memory model。此外,C++ 在实践中需要许多优化才能有效使用。
制作一个 error-free C++ 编译器 非常困难,特别是因为 C++ 实际上需要技巧 optimizations,并且因为C++规范的复杂性。但目前
那些(比如最近的 GCC 或 Clang)在实践中非常好,而且他们很少(但仍然有一些)
残留的编译器错误。目前还没有用于 C++ 的 CompCert++,制作一个需要数百万欧元或美元(但如果你能筹集到这么多钱,请通过电子邮件联系 me,例如 basile.starynkevitch@cea.fr
,我的工作邮箱)。 space 软件行业 极端 保守。
很难制作一个好的 C 或 C++ 堆内存分配器。编码
一个是trade-offs的事情。开个玩笑,考虑把this C heap allocator改编成C++。
证明安全性能(特别是,缺少race conditions or undefined behavior such as buffer overflow at run-time) of template-related C++ code is still, in 2Q2019, slightly ahead of the state of the art of static program analysis of C++ code. My draft Bismon technical report (it is a draft H2020 deliverable, so please skip pages for European bureaucrats) has several pages explaining this in more details. Be aware of Rice's theorem。
整个系统 C++ 嵌入式软件测试 可能需要火箭发射(la Ariane 5 test flight 501, or at least complex and heavy experimentation in lab). It is very expensive. Even testing, on Earth, a Mars rover 需要 很多的钱.
想一想:您正在编写一些 safety-critical 嵌入式软件(例如用于火车制动、自动驾驶汽车、自动无人机、大型石油平台或炼油厂、导弹等...)。你天真地使用一些 C++ 标准容器,例如一些 std::map<std::string,long>
。内存不足的情况应该怎么办?对于在资助 1 亿欧元 space 火箭的组织中工作的人,您 "prove" 或至少 "convince" 如何评价您的嵌入式软件(包括用于构建它的编译器)是好的足够的? decade-year 旧规则是禁止任何类型的动态堆分配。
I'm not talking about complex standard library stuff but purposed-made custom templates.
即使这些也很难证明,或者更笼统地评估它们的质量(您可能想使用自己的 allocator inside them). In space, the code space is a strong constraint. So you would compile with, for example, g++ -Os -Wall
or clang++ -Os -Wall
. But how did you prove -or simply test- all the subtle optimizations done by -Os
(and these are specific to your version of GCC or of Clang)? Your space funding organization will ask you that, since any run-time bug in embedded C++ space software can crash the mission (read again about Ariane 5 first flight failure - coded in some dialect of Ada which had at that time a "better" and "safer" type system than C++17 today), but don't laugh too much at Europeans. Boeing 737 MAX with its MACS is a similar mess)。
我个人的建议(但请不要太当真。在 2019 年,这更像是一个双关语)是考虑在 Rust. Because it is slightly safer than C++. Of course, you'll have to spend 5 to 10 M€ (or MUS$) in 5 or 7 years to get a fine Rust compiler, suitable for space computers (again, please contact me professionally, if you are capable of spending that much on a free software Compcert/Rust like compiler). But that is just a matter of software engineering and software project managements (read both the Mythical Man-Month and Bullshit jobs for more, be also aware of Dilbert principle 中编写您的 space 嵌入式软件:它既适用于 space 软件行业或嵌入式编译器行业,也适用于其他任何行业。
我强烈的个人观点是,欧盟委员会应该资助(例如通过 Horizon Europe) a free software CompCert++ (or even better, a Compcert/Rust) like project (and such a project would need more than 5 years and more than 5 top-class, PhD researchers). But, at the age of 60, I sadly know it is not going to happen (because the E.C. ideology -mostly inspired by German policies for obvious reasons- is still the illusion of the End of History, so H2020 and Horizon Europe are, in practice, mostly a way to implement tax optimizations for corporations in Europe through European tax havens), and that after several private discussions with several members of CompCert project. I sadly expect DARPA or NASA 更有可能资助一些未来的 CompCert/Rust 项目(而不是 E.C。资助它)。
注意。欧洲航空电子行业(主要是空客)正在使用更多 formal methods approaches that the North American one (Boeing). Hence some (not all) unit tests are avoided (since replaced by formal proofs of source code, perhaps with tools like Frama-C or Astrée - neither have been certified for C++, only for a subset of C forbidding C dynamic memory allocation and several other features of C). And this is permitted by DO-178C (not by the predecessor DO-178B) and approved by the French regulator, DGAC(我猜是其他欧洲监管机构)。
另请注意,许多 SIGPLAN 会议 间接 与 OP 的问题相关。
反对在安全代码中使用模板的论点是,它们被认为会增加代码的复杂性而没有实际好处。如果你有糟糕的工具和经典的安全理念,这个论点是有效的。举个例子:
template<class T> fun(T t){
do_some_thing(t);
}
在指定安全系统的经典方法中,您必须提供代码的每个功能和结构的完整描述。这意味着你不允许有任何没有规范的代码。这意味着您必须以一般形式给出模板功能的完整描述。由于显而易见的原因,这是不可能的。顺便说一句,这与 function-like 宏也被禁止的原因相同。如果您以描述此模板的所有实际实例化的方式改变想法,您就克服了这个限制,但您需要适当的工具来证明您确实描述了所有这些。
第二个问题是那个:
fun(b);
此行不是 self-contained 行。您需要查找 b 的类型才能知道实际调用了哪个函数。理解模板的适当工具在这里有所帮助。但在这种情况下,它确实使代码更难手动检查。
这种关于模板是漏洞原因的说法对我来说似乎完全不现实。主要有两个原因:
模板是 "compiled away",即实例化和 code-generated 与任何其他 function/member 一样,并且没有特定于它们的行为。就好像他们从未存在过一样;
任何语言的构造都不安全或易受攻击;如果一个电离粒子改变了一点内存,无论是代码还是数据,一切皆有可能(从没有出现明显的问题到处理器崩溃)。保护系统免受此影响的方法是添加硬件内存错误 detection/correction 功能。不是通过修改代码!
通过阅读
考虑到this answer,据说用起来很安全
注意:我说的不是复杂的标准库内容,而是特制的自定义模板。
注意 space-compatible(radiation-hardened, aeronautics compliant) computing devices are very expensive (including to launch in space, since their weight exceeds kilograms), and that a single space mission costs perhaps hundred million € or US$. Losing the mission because of software or computer concerns has generally a prohibitive cost so is unacceptable and justifies costly development methods and procedures that you won't even dream using for developing your mobile phone applet, and using probabilistic reasoning and engineering approaches is recommended, since cosmic rays are still somehow an "unusual" event. From a high-level point of view, a cosmic ray and the bit flip it produces can be considered as noise in some abstract form of signal or of input. You could look at that "random bit-flip" problem as a signal-to-noise ratio problem, then randomized algorithms may provide a useful conceptual framework (notably at the meta level, that is when analyzing your safety-critical source code or compiled binary, but also, at critical system run-time, in some sophisticated kernel or thread scheduler), with an information theory 观点。
Why C++ template use is not recommended in space/radiated environment?
该建议是对 MISRA C coding rules and of Embedded C++ rules, and of DO178C recommendations, and it is not related to radiation, but to embedded systems. Because of radiation and vibration constraints, the embedded hardware of any space rocket computer has to be very small (e.g. for economical and energy-consumption reasons, it is more -in computer power- a Raspberry Pi-like system than a big x86 server system). Space hardened chips cost 1000x much as their civilian counterparts. And computing the WCET on space-embedded computers is still a technical challenge (e.g. because of CPU cache related issues). Hence, heap allocation is frowned upon in safety-critical 嵌入式 software-intensive 系统的 泛化 ,C++(您将如何处理 out-of-memory 这些条件?或者你如何 证明 你有足够的 RAM 用于 所有 真实的 运行 时间案例?)
记得在安全-critical software world, you not only somehow "guarantee" or "promise", and certainly assess (often with some clever probabilistic reasoning), the quality of your own software, but also of all the software tools used to build it (in particular: your compiler and your linker; Boeing or Airbus won't change their version of GCC cross-compiler used to compile their flight control software without prior written approval from e.g. FAA or DGAC)。您的大多数软件工具都需要以某种方式获得批准或认证。
请注意,实际上,大多数 C++(但肯定不是全部)模板在内部使用堆。和标准 C++ containers certainly do. Writing templates which never use the heap is a difficult exercise. If you are capable of that, you can use templates safely (assuming you do trust your C++ compiler and its template expansion machinery, which is the trickiest part of the C++ front-end of most recent C++ compilers, such as GCC or Clang).
我猜出于类似的(工具集可靠性)原因,使用许多 source code generation tools (doing some kind of metaprogramming, e.g. emitting C++ or C code). Observe, for example, that if you use bison
(or RPCGEN) in some safety critical software (compiled by make
and gcc
), you need to assess (and perhaps exhaustively test) not only gcc
and make
, but also bison
. This is an engineering reason, not a scientific one. Notice that some embedded systems may use randomized algorithms, in particular to cleverly deal with noisy 输入信号(甚至可能由于 rare-enough 宇宙射线而随机位翻转)是不受欢迎的。证明、测试或分析(或只是评估)此类 random-based 算法是一个相当困难的话题。
另请查看 Frama-Clang and CompCert 并观察以下内容:
C++11(或以下)是一种极其复杂的编程语言。它没有完整的formal semantics。人民 足够精通 C++ 的人在全世界只有几十人(可能是大多数 其中的一部分在其标准委员会中)。我有能力编码 C++,但没有解释 move 的所有微妙的极端情况 语义,或 C++ memory model。此外,C++ 在实践中需要许多优化才能有效使用。
制作一个 error-free C++ 编译器 非常困难,特别是因为 C++ 实际上需要技巧 optimizations,并且因为C++规范的复杂性。但目前 那些(比如最近的 GCC 或 Clang)在实践中非常好,而且他们很少(但仍然有一些) 残留的编译器错误。目前还没有用于 C++ 的 CompCert++,制作一个需要数百万欧元或美元(但如果你能筹集到这么多钱,请通过电子邮件联系 me,例如
basile.starynkevitch@cea.fr
,我的工作邮箱)。 space 软件行业 极端 保守。很难制作一个好的 C 或 C++ 堆内存分配器。编码 一个是trade-offs的事情。开个玩笑,考虑把this C heap allocator改编成C++。
证明安全性能(特别是,缺少race conditions or undefined behavior such as buffer overflow at run-time) of template-related C++ code is still, in 2Q2019, slightly ahead of the state of the art of static program analysis of C++ code. My draft Bismon technical report (it is a draft H2020 deliverable, so please skip pages for European bureaucrats) has several pages explaining this in more details. Be aware of Rice's theorem。
整个系统 C++ 嵌入式软件测试 可能需要火箭发射(la Ariane 5 test flight 501, or at least complex and heavy experimentation in lab). It is very expensive. Even testing, on Earth, a Mars rover 需要 很多的钱.
想一想:您正在编写一些 safety-critical 嵌入式软件(例如用于火车制动、自动驾驶汽车、自动无人机、大型石油平台或炼油厂、导弹等...)。你天真地使用一些 C++ 标准容器,例如一些 std::map<std::string,long>
。内存不足的情况应该怎么办?对于在资助 1 亿欧元 space 火箭的组织中工作的人,您 "prove" 或至少 "convince" 如何评价您的嵌入式软件(包括用于构建它的编译器)是好的足够的? decade-year 旧规则是禁止任何类型的动态堆分配。
I'm not talking about complex standard library stuff but purposed-made custom templates.
即使这些也很难证明,或者更笼统地评估它们的质量(您可能想使用自己的 allocator inside them). In space, the code space is a strong constraint. So you would compile with, for example, g++ -Os -Wall
or clang++ -Os -Wall
. But how did you prove -or simply test- all the subtle optimizations done by -Os
(and these are specific to your version of GCC or of Clang)? Your space funding organization will ask you that, since any run-time bug in embedded C++ space software can crash the mission (read again about Ariane 5 first flight failure - coded in some dialect of Ada which had at that time a "better" and "safer" type system than C++17 today), but don't laugh too much at Europeans. Boeing 737 MAX with its MACS is a similar mess)。
我个人的建议(但请不要太当真。在 2019 年,这更像是一个双关语)是考虑在 Rust. Because it is slightly safer than C++. Of course, you'll have to spend 5 to 10 M€ (or MUS$) in 5 or 7 years to get a fine Rust compiler, suitable for space computers (again, please contact me professionally, if you are capable of spending that much on a free software Compcert/Rust like compiler). But that is just a matter of software engineering and software project managements (read both the Mythical Man-Month and Bullshit jobs for more, be also aware of Dilbert principle 中编写您的 space 嵌入式软件:它既适用于 space 软件行业或嵌入式编译器行业,也适用于其他任何行业。
我强烈的个人观点是,欧盟委员会应该资助(例如通过 Horizon Europe) a free software CompCert++ (or even better, a Compcert/Rust) like project (and such a project would need more than 5 years and more than 5 top-class, PhD researchers). But, at the age of 60, I sadly know it is not going to happen (because the E.C. ideology -mostly inspired by German policies for obvious reasons- is still the illusion of the End of History, so H2020 and Horizon Europe are, in practice, mostly a way to implement tax optimizations for corporations in Europe through European tax havens), and that after several private discussions with several members of CompCert project. I sadly expect DARPA or NASA 更有可能资助一些未来的 CompCert/Rust 项目(而不是 E.C。资助它)。
注意。欧洲航空电子行业(主要是空客)正在使用更多 formal methods approaches that the North American one (Boeing). Hence some (not all) unit tests are avoided (since replaced by formal proofs of source code, perhaps with tools like Frama-C or Astrée - neither have been certified for C++, only for a subset of C forbidding C dynamic memory allocation and several other features of C). And this is permitted by DO-178C (not by the predecessor DO-178B) and approved by the French regulator, DGAC(我猜是其他欧洲监管机构)。
另请注意,许多 SIGPLAN 会议 间接 与 OP 的问题相关。
反对在安全代码中使用模板的论点是,它们被认为会增加代码的复杂性而没有实际好处。如果你有糟糕的工具和经典的安全理念,这个论点是有效的。举个例子:
template<class T> fun(T t){
do_some_thing(t);
}
在指定安全系统的经典方法中,您必须提供代码的每个功能和结构的完整描述。这意味着你不允许有任何没有规范的代码。这意味着您必须以一般形式给出模板功能的完整描述。由于显而易见的原因,这是不可能的。顺便说一句,这与 function-like 宏也被禁止的原因相同。如果您以描述此模板的所有实际实例化的方式改变想法,您就克服了这个限制,但您需要适当的工具来证明您确实描述了所有这些。
第二个问题是那个:
fun(b);
此行不是 self-contained 行。您需要查找 b 的类型才能知道实际调用了哪个函数。理解模板的适当工具在这里有所帮助。但在这种情况下,它确实使代码更难手动检查。
这种关于模板是漏洞原因的说法对我来说似乎完全不现实。主要有两个原因:
模板是 "compiled away",即实例化和 code-generated 与任何其他 function/member 一样,并且没有特定于它们的行为。就好像他们从未存在过一样;
任何语言的构造都不安全或易受攻击;如果一个电离粒子改变了一点内存,无论是代码还是数据,一切皆有可能(从没有出现明显的问题到处理器崩溃)。保护系统免受此影响的方法是添加硬件内存错误 detection/correction 功能。不是通过修改代码!