10

我是一名 C++ 程序员,多年来一直听说 STL适合在嵌入式环境中使用,因此通常禁止在基于嵌入式环境的项目中使用。我相信像 Boost 这样的 STL 库功能更强大并提供一种更快、更不容易出错的开发方式(当然,语法有点吓人,但一旦过去,我认为它是一个真正的宝藏)。另外,我发现 STL 很重并且增加了代码的最终足迹的说法是荒谬的,因为它被模板化的人只会得到他要求的可编译代码,而不是整个 STL。

我的问题是,这种称为 STL 的民粹主义(至少我周围的大多数人都这么认为)概念不适用于嵌入式环境的原因是什么?

我确实看到了一个类似性质的问题,但在这里我期待帮助指出关于 STL 和嵌入式环境的一般优缺点。

编辑:所以在这里我将在收到回复时添加要点:
1. 可移植性问题
2. 应对 STL 容器的巨大 dymanice 分配
3. STL 难以调试
4. STL 中的深度函数调用导致编译器性能低下内联弱(函子的力量无用!)

4

11 回答 11

9

在嵌入式系统或小型系统上,STL 有很多问题(如EASTL所记录的),主要问题通常是它管理(其)内存的方式。一个很好的例子是Aquaria 的 PSP 端口

不过我的建议是在遵循假设之前先进行测试,如果测试显示您使用了过多的空间/处理器周期,那么也许一两次优化可以将其推向“可用”领域。

最后,boost 是基于模板的,所以如果你查看生成的模板代码的大小,它会受到与 STL 相同的影响。

编辑/更新:

澄清我的最后一个陈述(这只是指boost VS STL)。在 C 语言中,您可以(ab)使用相同的代码在共享相同标题(或布局)的不同结构上执行相同的工作,但是使用模板,每种类型都可能有自己的副本(我从未测试过是否有任何编译器如果启用了“优化尺寸”,则足够聪明地做到这一点),即使它与刚刚生成的完全相同(在机器/装配级别上)。boost 的优点是阅读起来更干净,并且可以塞进更多的东西,但是由于大量(有时是巨大的)标头,这可能导致编译时间长。STL 收益是因为您可以传递您的项目,而不需要下载/伴奏 boost。

于 2010-10-04T07:45:07.200 回答
8

这取决于您所说的嵌入式。在 Atmel8 系统上,内存很少。如此之少,以至于您无法真正拥有合理的malloc。在这种情况下,您希望非常明确地管理内存,可能使用您需要的类型的静态数组。如果你有这个,你基本上不需要大部分的 STL。

在 arm 系统上,您有足够的内存。使用 STL!

于 2010-10-04T07:44:11.290 回答
3

我遇到了这个演示文稿:用于嵌入式系统编程的标准 C++

模板的大部分复杂性在于编译器而不是运行时系统,这部分是问题所在 - 因为我们不确定编译器能够完成多少优化。事实上,基于 STL 的 C++ 代码应该比不使用模板甚至 C 代码的 C++ 代码更紧凑、更快速!

于 2010-10-04T08:03:35.893 回答
3

模板导致更大代码的概念背后有一些逻辑。基本思想非常简单:模板的每个实例化都产生基本上独立的代码。这对于早期的编译器来说尤其成问题——因为模板(通常)必须放在头文件中,所以模板中的所有函数都是inline. 这意味着如果您(例如)vector<int>在 10 个不同的文件中实例化,则(理论上)您使用的每个成员函数都有 10 个单独的副本,一个用于您使用它的每个文件。

任何相当新的编译器(例如,不到 10 年)都会在链接器中有一些逻辑将它们重新合并在一起,因此vector<int>跨 10 个文件实例化只会导致您使用的每个成员函数的一个副本进入最终的可执行文件。然而,无论好坏,一旦“知道”模板会产生臃肿的代码,很多人就没有再看它是否仍然正确。

另一点(仍然如此)是模板可以很容易地创建一些非常复杂的代码。如果你用 C 自己写东西,你通常会强烈地使用最简单的算法、集合等来完成这项工作——足够的动机,你可能会检查诸如最大数量之类的细节您可能会遇到的项目,看看您是否可以摆脱一些非常简单的事情。模板可以使使用通用集合变得如此容易,以至于您不必费心检查类似的事情,因此(例如)您最终获得了构建和维护平衡树的所有代码,即使您只是最多存储(例如)10 个项目,因此具有线性搜索的简单数组可以节省内存并且通常运行速度也更快。

于 2010-10-04T08:44:45.493 回答
2

我认为选择取决于您的目标平台。如果你有一个正确的 C++ 编译器,并且不介意使用容器时动态分配的内存,我认为没有任何问题。

于 2010-10-04T07:41:12.950 回答
2

正如人们所说,有各种各样的“嵌入式”系统。我将给出我的观点,重点关注安全关键和硬实时系统。

大多数安全关键系统指南都简单地禁止使用动态内存分配。如果您永远不必担心 malloc/new 调用失败,那么设计程序会更容易和更安全。对于可能发生堆碎片的长时间运行的系统,您无法轻易证明内存分配不会失败,即使在具有大量内存的芯片/系统上(尤其是当设备必须运行多年而不重新启动时)。

在时间期限紧迫的情况下,动态内存分配和复杂对象实例化所涉及的不确定性通常太大而无法处理。这就是为什么许多在这些领域工作的程序员坚持使用 C 的原因。您可以查看 C 源代码并猜测一个操作需要多长时间。使用 C++,看起来简单的代码更容易花费比看起来更长的时间。那些在此类系统中使用 C++ 的人倾向于坚持使用简单的普通代码。通常速度很快但有时需要很长时间才能执行的代码比速度较慢但始终如一的代码更糟糕。

我在大型项目中所做的是将实时和关键功能与其他功能隔离开来。可以使用 STL 等标准工具编写非关键内容。只要操作系统不妨碍关键部分,就可以了。如果我不能保证没有这样的交互,那么就不要使用这些工具。

于 2010-10-04T12:30:51.657 回答
2

我在一个嵌入式项目中使用 C++ 和 STL,系统非常受限(内存只有几兆字节,ARMv4 低速)。在大多数情况下,STL 很棒,但有些部分我们不得不跳过(例如,std::map 每次实例化需要 2-4k 的代码 [这相对于我们的 ROM 大小来说是一个很大的数字],我们有我们自己对 std::bitset 的自定义替换 [它可能是 ~1k ROM])。但是,std::vector 和 std::list 非常有用,就像使用 boost::intrusive_ptr 进行引用计数一样(shared_ptr 太大了,每个对象大约 40 字节 RAM!)。

使用 STL 的一个缺点是当异常被关闭时你没有错误恢复(它们是为我们准备的,因为异常和 RTTI 在我们的编译器上并不便宜)。例如,如果内存分配在此行代码中的某处失败(std::map 对象):

my_map[5] = 66;

你不会看到它,代码只会默默地继续前进;很可能该对象现在处于损坏状态,但直到很久以后您才会崩溃。

话虽如此,我们在 C++ 和 STL 方面取得了巨大成功。正如另一位发帖人所说,在您的系统上试用并衡量 STL 的哪些部分有效。作为旁注,有一份关于 C++ 性能的一般技术报告很好读: http ://www.open-std.org/jtc1/sc22/wg21/docs/TR18015.pdf

于 2010-10-04T15:49:19.077 回答
1

许多人认为(出于多种原因,例如可移植性)C++ 不适合嵌入式环境。嵌入式环境有很多种类型,STL 对于其中的一些当然是可以的。

一般来说,当您需要为资源受限的环境选择任何东西时,“更强大”总是一个令人害怕的短语,因为您通常想要一些功能不那么强大且更可控的东西。特别是如果“更强大”意味着开发人员(或以后维护代码的人)对底层实现的了解较少。

于 2010-10-04T07:37:50.883 回答
1

这取决于嵌入式系统的性质。

这样的系统可能有几千字节(或更少)的 RAM,或者它可能有许多兆字节甚至千兆字节。所以内存限制可能是也可能不是问题。

If the system has real-time constraints, some parts or usages of STL may not be suited to some parts of your application. Container classes rely heavily on dynamic memory allocation, reallocation and object copying, and this is most often highly non-deterministic, so when used in time-critical code, you have no way of guaranteeing the meeting of deadlines.

That is not to say that it STL cannot be used, even in real-time applications. But you need to design the code carefully so that you will know that some non-deterministic operation will not occur during a time critical process.

于 2010-10-04T19:06:08.417 回答
0

对我来说,只有很好的理由,如果某些库不符合有限的约束,或者它的大小以后可能会出现问题,则不要使用它。如果这对你来说不是问题,那就去吧。在任何情况下你都无法变得更好。

于 2010-10-04T08:16:57.050 回答
0

我没有遇到在嵌入式系统中使用 STL 的任何缺点,我计划在我当前的项目中使用它。升压也是如此。

于 2010-10-04T08:23:12.993 回答