我正在开发一个软件库,用于嵌入式系统,如ARM芯片或TI DSP(主要用于嵌入式系统,但如果它也可用于PC环境,那也很不错)。显然,这是一个非常广泛的目标系统,因此能够轻松移植到不同的系统是一个优先事项。该库将用于与特定硬件接口并运行一些算法。
我认为C ++是C语言的最佳选择,因为它更易于维护和阅读。我认为额外的开销是值得的,因为它能够在面向对象的范例中工作。如果我是为一个非常具体的系统编写的,我会在C中工作,但事实并非如此。
我认为现在大多数流行嵌入式系统的编译器都可以处理C ++。它是否正确?
我还应该考虑其他因素吗?我的思路是否正确?
答案 0 :(得分:8)
如果可移植性对您来说非常重要,特别是在嵌入式系统上,那么C肯定是比C ++更好的选择。虽然嵌入式平台上的C ++编译器正在迎头赶上,但是C的广泛使用并不匹配,因为任何自尊平台都有兼容的编译器。
此外,我不认为C在连接硬件方面不如C ++。抽象量足够低(即没有深层次的层次结构),使C成为一个很好的选择。
答案 1 :(得分:7)
对于ARM,C ++肯定有很好的支持。 ARM有自己的编译器和g ++也可以生成符合EABI的ARM代码。对于DSP,你必须查看他们的工具链来决定你将要做什么。请注意,DSP附带的库可能无法实现完整的C或C ++标准库。
C ++适用于低级嵌入式开发,用于SymbianOS内核。话虽如此,你应该尽可能地保持简单。
答案 2 :(得分:5)
我看到许多抱怨C ++“膨胀”并且不适合嵌入式系统。
然而,在接受Stroustrup和Sutter采访时,Bjarne Stroustrup提到他看到了大量模板化的C ++代码进入(IIRC)宝马制动系统,以及战斗机导弹制导系统。
我从这里得到的是,该语言的专家可以用C ++生成复杂,高效的代码,这些代码当然适用于嵌入式系统。但是,“C With Classes”[1]程序员不知道里面的语言会生成不合适的膨胀代码。
问题归结为一如既往:您的团队可以用哪种语言提供最好的产品?
[1]我知道这听起来有些贬义,但是我要说我认识了很多这些人,并且他们制作了大量相对简单的代码来完成工作。
答案 3 :(得分:4)
嵌入式平台的C ++编译器更接近83的C类,而不是98的C ++标准,更不用说C ++ 0x了。例如,我们使用的某个平台仍然使用gcc-2.95创建的特殊版本的gcc编译!
这意味着您的库接口将无法提供容器/迭代器,流或此类高级 C ++功能的接口。你必须坚持使用简单的C ++类,它们很容易被表达为一个C接口,并指向一个结构作为第一个参数。
这也意味着在您的图书馆中,您将无法使用模板来充分发挥其功能。如果你想要可移植性,你仍然只能使用通用容器使用模板,我相信你会承认,只有很小一部分C ++模板供电。
答案 4 :(得分:2)
如果在嵌入式环境中正确使用,C ++与C相比几乎没有开销。 C ++在信息隐藏,OO等方面有很多优点。如果C语言中的gcc支持嵌入式处理器,那么C ++也可能支持它。
答案 5 :(得分:1)
在PC上,C ++根本不是问题 - 高质量的编译器非常普遍,几乎每个C编译器都直接与C ++编译器相关联,这很好,尽管有一些例外,如lcc和新复活的pcc。
基于ARM的大型嵌入式系统在工具链可用性方面通常与桌面系统非常相似。实际上,许多可用于桌面计算机的相同工具也可以生成在基于ARM的计算机上运行的代码(例如,其中许多使用gcc / g ++的端口)。 TI DSP的种类较少(并且比源代码功能更强调生成代码的质量),但仍然至少有几个可敬的C ++编译器可供使用。
如果您想使用较小的嵌入式系统,情况会变得匆忙。如果你想能够像PIC或AVR这样的目标,C ++并不是一个很好的选择。从理论上讲,你可以得到(例如)Comeau来生成一个自定义端口,生成可以在该目标的C编译器上编译的代码 - 但是很有可能即使你这样做,它也不会很好。这些系统实际上对C ++的限制(特别是内存大小)非常适合它们。
答案 6 :(得分:1)
根据您对图书馆的预期用途,我认为我建议首先将其作为C实现 - 但设计应牢记如何将其合并到C ++设计中。然后在C实现的顶部和/或旁边实现C ++类(没有理由这个步骤不能与第一个同时完成)。如果您的C设计是在考虑C ++设计的情况下完成的,那么它可能与C ++设计一样干净,可读和可维护。这是一些更多的工作,但我认为你最终会得到一个在更多情况下有用的库。
虽然你会发现C ++在各种嵌入式项目中的使用越来越多,但仍然有很多人将自己限制在C语言中(而且我猜这种情况通常不是这样) - 无论是否使用这些工具支持C ++。如果有一个很好的例程库可以带给你正在处理的新项目,但却无法使用它们,因为C ++没有在那个特定的项目上使用,这将是一种遗憾。
一般来说,使用C ++设计良好的C库比使用其他方法要容易得多。我采用了这种方法,包括解析Intel Hex文件,简单的命令解析器,操作同步对象,FSM框架等等。我计划在某些时候做一个简单的XML解析器。
答案 7 :(得分:0)
这是一个完全不同的C ++ - vs-C参数:稳定的ABI。如果您的库导出C ABI,则可以使用在系统上运行的任何编译器进行编译,因为C ABI通常是平台标准。如果您的库导出C ++ ABI,它只能使用匹配的编译器进行编译 - 因为C ++ ABI通常不是平台标准,并且通常因编译器和编译器而不同,甚至版本也不同。
有趣的是,其中一个罕见的例外是ARM;有一个ARM C ++ ABI规范,所有兼容的ARM编译器都遵循它。在x86上不是这样;在x86上,如果使用4.1版本的GCC编译的C ++库与使用GCC 4.4编译的应用程序正确链接,并且甚至不询问3.4.6,那么你很幸运。
即使您导出C ABI,也可能会出现问题。如果您的库在内部使用C ++,那么它将链接到libstdc ++以获取C ++ std :: namespace中的内容。如果您的用户编译使用您的库的C ++应用程序,它们也会链接到libstdc ++ - 因此整个应用程序会链接到libstdc ++两次,而它们的libstdc ++可能与您的libstdc ++不兼容,这可能(或者我理解) )导致两者交叉的奇怪错误。相当不太可能,但仍有可能。
所有这些参数仅适用,因为你正在编写一个库,而且它们不是showstoppers。但是他们需要注意的事情。