问题
我的硬件上有两个编译器C++和C89
我正在考虑对类使用C++,但不使用多态性(以避免使用vtables)。我想使用C++的主要原因是:
在为非常有限的硬件(4kb内存)进行开发时,您认为有任何理由坚持使用C89吗?
结论
谢谢你的回答,他们真的很有帮助!
我仔细考虑了这个主题,我将继续使用C语言,主要是因为:
很难接受一个答案,因为你提供了这么多好的答案。不幸的是,我不能创建一个wiki并接受它,所以我会选择一个让我思考最多的答案。
发布于 2009-05-02 16:58:30
在C++上使用C有两个原因:
另外,原始问题和许多评论都提到了4KB的RAM。对于典型的嵌入式处理器,RAM的大小(大部分)与代码大小无关,因为代码存储在闪存中,并从闪存运行。
当然,代码存储空间的数量是需要牢记的,但随着新的、更大容量的处理器出现在市场上,除了对成本最敏感的项目之外,这不是过去所有项目的问题。
关于在嵌入式系统中使用C++的一个子集:现在有一个MISRA C++标准,这可能值得一看。
编辑:另请参阅this question,它引发了一场关于嵌入式系统的C与C++的争论。
发布于 2009-05-01 20:55:08
对于资源非常有限的目标,比如4KB的RAM,我会先用一些样本进行测试,然后再进行大量的工作,这些工作不能轻松地移植回纯ANSI C实现中。
嵌入式C++工作组确实提出了该语言的标准子集和标准库的标准子集。不幸的是,当C用户日志死掉的时候,我忘记了这一努力。看起来像是Wikipedia上有一篇文章,而且committee仍然存在。
在嵌入式环境中,您真的必须小心内存分配。要强制实施这种关注,您可能需要将全局operator new()
及其朋友定义为甚至不能链接的内容,以便您知道它未被使用。另一方面,Placement new
很可能是您的朋友,当它与稳定的、线程安全的和延迟保证的分配方案一起明智地使用时。
内联函数不会造成太多问题,除非它们足够大,以至于它们本来就应该是真正的函数。当然,它们所替换的宏也有同样的问题。
模板也可能不会造成问题,除非它们的实例化运行失控。对于您使用的任何模板,审核您生成的代码(链接映射可能有足够的线索),以确保只发生了您打算使用的实例化。
可能出现的另一个问题是与调试器的兼容性。对于其他可用的硬件调试器来说,对与原始源代码交互的支持非常有限,这并不罕见。如果您必须有效地在汇编中进行调试,那么有趣的C++名称混乱可能会给任务增加额外的混乱。
RTTI、动态类型转换、多重继承、重多态性和异常都会为它们的使用带来一定的运行时成本。如果使用这些特性,其中一些特性会使整个程序的成本降低,而其他特性只会增加需要它们的类的权重。了解差异,并在充分了解粗略的成本/收益分析的情况下明智地选择高级功能。
在小型嵌入式环境中,您可以直接链接到实时内核,也可以直接在硬件上运行。无论哪种方式,您都需要确保您的运行时启动代码正确处理特定于C++的启动琐事。这可能与确保使用正确的链接器选项一样简单,但由于直接控制通电重置入口点的源是很常见的,因此您可能需要对其进行审计,以确保它完成了所有操作。例如,在我工作的ColdFire平台上,开发工具附带了一个CRT0.S模块,该模块提供了C++初始化器,但将其注释掉。如果我直接使用它,我会对全局对象感到困惑,因为它们的构造函数根本就没有运行过。
此外,在嵌入式环境中,通常需要在使用硬件设备之前对其进行初始化,如果没有操作系统和引导加载程序,则执行此操作的是您的代码。您需要记住,全局对象的构造函数是在调用main()
之前运行的,因此您需要修改本地CRT0.S (或其等效项),以便在调用全局构造函数之前完成硬件初始化。显然,main()
的顶部已经太晚了。
发布于 2009-05-01 18:55:54
不是的。任何可能导致问题的C++语言特性(运行时多态性、RTTI等)在进行嵌入式开发时可以避免。有一个嵌入式C++开发人员社区(我记得在旧的C/C++用户杂志上读过嵌入式开发人员使用C++的专栏),如果选择这么糟糕,我不能想象他们会非常直言不讳。
https://stackoverflow.com/questions/812717
复制相似问题