我是一名C ++程序员,多年来一直听说STL 不好 这一概念在嵌入式环境中使用,因此通常禁止使用基于嵌入式环境的项目。我相信像Boost这样的STL库功能更强大,提供更快更好的速度。不那么容易出错的开发方式(当然语法有点吓人,但一旦过去,我认为这是一个真正的宝藏)。而且,我发现STL很重要并且增加代码荒谬的最终足迹的说法因为它是模板化的,所以只是要获得他要求的可编译代码而不是整个STL。
我的问题是,这个民粹主义者(至少在我身边的大多数人都是这么认为)这个概念的原因是什么?STL对于嵌入式环境来说是 而不是 ?
我确实看到了类似性质的问题,但在此我希望能帮助指出STL和嵌入环境的一般优缺点。
编辑:所以我会在回复中加上积分:
1.便携性问题
2.应对STL集装箱巨大的动态分配
3. STL很难调试
4. STL中的深度函数调用会导致编译器的内联性能低下(内置函数无用!)
答案 0 :(得分:9)
STL有很多问题(如EASTL所述),在嵌入式系统或小规模系统上,主要问题通常是它管理(内存)的方式。一个很好的例子就是PSP port of Aquaria。
我的建议是第一次测试,在遵循假设之前,如果测试显示您使用了太多的空间/处理器周期,那么可能是一个优化或两个可以将其推入'可用”。
最后,boost是基于模板的,所以如果你查看生成的模板代码的大小,它将与STL相同。
修改/更新强>
清理我的最后一句话(这只是提到VS VS STL)。在C中,你可以(ab)使用相同的代码在共享相同标题(或布局)的不同结构上执行相同的工作,但是使用模板,每种类型都可以获得自己的副本(我从不测试任何编译器是否是如果“优化大小”被提升,那么即使它与刚刚生成的完全相同(在机器/组件级别上)也足够聪明。 boost具有读取更清晰,并且有更多东西塞进其中的优点,但是由于大量(巨大的)标题,这会导致编译时间过长。 STL获益是因为你可以通过你的项目,而不需要下载/伴随升级。
答案 1 :(得分:8)
这取决于您对嵌入式的含义。在Atmel8系统上,只有很少的内存。这么少,你真的没有一个合理的malloc。在这种情况下,您希望非常明确地管理内存,可能使用所需类型的静态数组。如果你有这个,你基本上不需要大部分的STL。
在手臂系统上,你有很多公羊。使用STL!
答案 2 :(得分:3)
我看到了这个演示文稿:Standard C++ for Embedded Systems Programming
模板的大部分复杂性在于编译器而不是在运行时系统中,部分问题在于 - 因为我们不确定编译器能够完成多少优化。事实上,基于STL的C ++代码应该比不使用模板甚至C代码的C ++代码更紧凑,更快!
答案 3 :(得分:3)
模板导致更大代码的概念背后有一些逻辑。基本思想非常简单:模板的每个实例化都会产生基本上独立的代码。这对早期编译器来说尤其成问题 - 因为模板(通常)必须放入标题中,模板中的所有函数都是inline
。这意味着如果您(例如)vector<int>
在10个不同的文件中实例化,那么(理论上)您使用的每个成员函数有10个单独的副本,每个文件对应一个您使用它的文件。
任何合理的最新编译器(少于,比如说,10年)都会在链接器中有一些逻辑将这些逻辑合并在一起,因此在10个文件中实例化vector<int>
只会导致每个成员函数的一个副本你用到了最后的可执行文件。然而,无论好坏,一旦“知道”模板产生臃肿的代码,很多人都没有再看过它是否仍然存在。
另一点(仍然如此)是模板可以轻松创建一些非常复杂的代码。如果你在C中自己写东西,你通常会有很强的动力去使用最简单的算法,集合等来完成这项工作 - 这足以让你有可能检查出最大数量这样的细节。你可能会遇到的项目,看看你是否可以逃脱一些非常简单的事情。一个模板可以很容易地使用通用集合,你不需要检查这样的东西,所以(例如)你最终得到所有代码来构建和维护一个平衡的树,即使你只是最多存储(比方说)10个项目,因此使用线性搜索的简单数组可以节省内存,并且通常也可以更快地运行。
答案 4 :(得分:2)
我认为选择取决于您的目标平台。如果你有一个正确的C ++编译器,如果你使用容器不介意动态分配的内存,我没有看到任何问题。
答案 5 :(得分:2)
正如人们所说,有很多“嵌入式”系统。我将提出我的观点,重点关注安全关键和硬实时系统。
安全关键系统的大多数指南都禁止使用动态内存分配。如果您不必担心malloc / new呼叫失败,那么设计程序会更容易,更安全。对于可能发生堆碎片的长时间运行的系统,即使在具有大量内存的芯片/系统上(特别是当设备必须运行多年而不重新启动时),您也无法轻易证明内存分配不会失败。
在时间紧迫的最后期限的情况下,动态内存分配和复杂对象实例化所涉及的不确定性通常太大而无法处理。这就是为什么许多在这些领域工作的程序员都坚持使用C.你可以查看C源代码并猜测操作需要多长时间。使用C ++,简单外观的代码比看起来更容易。那些在这种系统中使用C ++的人倾向于坚持使用简单的普通代码。通常速度很快但有时需要很长时间才能执行的代码比速度慢但一致的代码更糟糕。
我在大型项目中所做的是将实时和关键功能与其他功能隔离开来。可以使用STL等标准工具编写非关键内容。只要操作系统不妨碍关键部件,那就没问题。如果我不能保证没有这样的交互,那么根本不要使用这些工具。
答案 6 :(得分: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
答案 7 :(得分:1)
许多人认为(出于诸多原因,例如可移植性)C ++不适合嵌入式环境。有许多类型的嵌入式环境,STL对于其中一些肯定是可以的。
一般来说,当你需要为资源有限的环境选择任何东西时,“更强大”总是一个恐惧的短语,因为你经常想要一些不那么强大和更可控的东西。特别是如果“更强大”意味着开发人员(或者以后维护代码的人)对底层实现的理解会更少。
答案 8 :(得分:1)
这取决于嵌入式系统的性质。
这样的系统可能有几千字节的RAM(或更少),或者可能有几兆字节甚至几千兆字节。所以内存限制可能是也可能不是问题。
如果系统有实时约束,STL的某些部分或用法可能不适合您应用程序的某些部分。容器类在很大程度上依赖于动态内存分配,重新分配和对象复制,而这通常是高度不确定的,因此当用于时间关键代码时,您无法保证最后期限的会议。
这并不是说即使在实时应用程序中也不能使用STL。但是您需要仔细设计代码,以便您知道在时间关键过程中不会发生某些非确定性操作。
答案 9 :(得分:0)
对我来说,只有充分的理由,如果它不适合有限的约束或者它的大小以后可能会有问题,不使用某些库。如果这不是问题,那就去吧。在任何情况下,你都无法变得更好。
答案 10 :(得分:0)
我没有遇到过在嵌入式系统中使用STL的任何缺点,我打算在我当前的项目中使用它。也提升了。