c++ - 是否有任何理由使用 C 而不是 C++ 进行嵌入式开发?

标签 c++ c embedded c89

问题

我的硬件 C++ 和 C89 上有两个编译器

我正在考虑将 C++ 与类一起使用,但不使用多态性(以避免使用 vtables)。 我想使用 C++ 的主要原因是:

  • 我更喜欢使用“内联”函数而不是宏定义。
  • 我想使用命名空间,因为我的前缀会使代码困惑。
  • 我认为 C++ 类型更安全,主要是因为模板和详细的转换。
  • 我真的很喜欢重载的函数和构造函数(用于自动转换)。

在为非常有限的硬件(4kb 的 RAM)进行开发时,您认为有什么理由坚持使用 C89?

结论

感谢您的回答,他们真的很有帮助!

我想通了这个主题,我会坚持使用 C 主要是因为:

  1. 用 C 语言预测实际代码更容易,如果您只有 4kb 的内存,这一点非常重要。
  2. 我的团队主要由 C 开发人员组成,因此不会经常使用高级 C++ 功能。
  3. 我找到了一种在我的 C 编译器 (C89) 中内联函数的方法。

您提供了这么多好的答案,很难接受一个答案。 不幸的是,我无法创建一个 wiki 并接受它,所以我会选择一个让我思考最多的答案。

最佳答案

对于一个非常资源受限的目标,例如 4KB 的 RAM,我会先用一些样本试水,然后再投入大量的努力,这些努力无法轻易移植回纯 ANSI C执行。

嵌入式 C++ 工作组确实提出了该语言的标准子集和标准库的标准子集以与之配套。不幸的是,当 C User's Journal 死了时,我忘记了这项工作。 Wikipedia好像有文章,而 committee仍然存在。

在嵌入式环境中,您确实必须小心内存分配。为了强制执行这种注意,您可能需要将全局 operator new() 及其 friend 定义为甚至无法链接的东西,以便您知道它没有被使用。另一方面,如果与稳定、线程安全和延迟保证的分配方案一起明智地使用,放置 new 可能会成为您的 friend 。

内联函数不会造成太大问题,除非它们足够大以至于它们本来应该是真正的函数。当然,它们替换的宏也有同样的问题。

模板也可能不会导致问题,除非它们的实例化运行异常。对于您使用的任何模板,请审核您生成的代码(链接映射可能有足够的线索)以确保仅发生您打算使用的实例化。

另一个可能出现的问题是与您的调试器的兼容性。其他可用的硬件调试器对与原始源代码交互的支持非常有限,这并不罕见。如果您实际上必须在汇编中进行调试,那么有趣的 C++ 名称修饰可能会给任务增加额外的困惑。

RTTI、动态转换、多重继承、重多态性和异常都伴随着使用它们的一些运行时成本。如果使用这些功能,其中一些功能会花费整个程序的成本,其他功能只会增加需要它们的类的权重。了解差异,明智地选择高级功能,至少了解粗略的成本/ yield 分析。

在小型嵌入式环境中,您将直接链接到实时内核或直接在硬件上运行。无论哪种方式,您都需要确保您的运行时启动代码正确处理 C++ 特定的启动杂务。这可能就像确保使用正确的链接器选项一样简单,但由于通常可以直接控制通电复位入口点的源,因此您可能需要对其进行审核以确保它可以完成所有操作。例如,在我工作的一个 ColdFire 平台上,开发工具附带了一个 CRT0.S 模块,该模块具有 C++ 初始化程序,但注释掉了。如果我直接使用它,我会被其构造函数根本没有运行过的全局对象迷惑。

此外,在嵌入式环境中,通常需要先初始化硬件设备才能使用它们,如果没有操作系统和引导加载程序,那么就是您的代码执行此操作。您需要记住,全局对象的构造函数在 main() 调用之前运行,因此您需要修改本地 CRT0.S(或其等效项)以获取硬件初始化在调用全局构造函数之前完成。显然,main() 的顶部已经来不及了。

关于c++ - 是否有任何理由使用 C 而不是 C++ 进行嵌入式开发?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/812717/

相关文章:

c++ - 声明一个具有 C 调用约定但具有内部链接的 C++ 函数

c:计算中使用的赋值

c - 在 BEA Tuxedo 中,在 tpreturn 之后调用 tpfree 有意义吗?

c - 动态字符数组大小调整

c++ - 在 C++ 中将一维数组作为二维数组访问

c++ - C++ 库中的自动初始化例程?

不能接受多个命令行参数并分配给变量

c - Atmel 处理器已复位,但 MCUSR 中未指示复位源

c - 看门狗在高中断率时触发

c++ - 模板enable_if函数实现是否可行?