【问题标题】:Arduino C++ code: can you use virtual functions and exceptions?Arduino C++ 代码:可以使用虚函数和异常吗?
【发布时间】:2023-03-30 15:48:01
【问题描述】:

从问题Writing firmware: assembly or high level?跟进this comment

在为Arduino平台编译C++代码时,可以使用虚函数、异常等吗?或者您想(必须)使用 C++ 的一个子集(如the comment 中所述)?

为 Arduino 平台编程时还有其他注意事项吗?

【问题讨论】:

    标签: c++ arduino virtual-functions firmware


    【解决方案1】:

    Arduino 环境使用 GCC 工具链的 AVR 版本。代码编译为 C++,因此您可以使用类。虚拟功能是可能的; vtables 将存储在 .data 部分并具有正确的地址。事实上,Print 基类使用虚函数来使各种“打印”方法适应不同的输出类型。

    由于代码空间原因,不支持异常。 Arduino 环境将“-fno-exceptions”传递给编译器命令行。请参阅the source 进行验证。

    支持模板。例如,this no-cost stream insertion operator technique 使用简单的模板和内联运算符即可正常工作。

    【讨论】:

      【解决方案2】:

      Arduino 软件使用 avr-gcc 编译草图。以下限制来自avrlibc FAQ (Can I use C++ on the AVR?)

      支持

      • 虚拟函数
      • 构造函数和析构函数(包括全局函数)

      不支持

      • C++ 标准函数、类和模板类(但请参阅this port of uClibc++ for Arduino
      • 运算符newdelete(尝试使用它们会导致链接器抱怨未定义的外部引用)。这意味着对象只能在堆栈上创建。如果需要动态内存分配,则必须使用C 类型的malloc()free() 来实现
      • 例外。由于 C++ 前端默认启用异常,因此需要在编译器选项中使用 -fno-exceptions 明确关闭它们。这是由 Arduino IDE 在启动 avr-gcc 时自动完成的

      其他问题

      • 提供的一些包含文件不是 C++ 安全的,即它们需要用
        extern "C" { . . . }
      • 包装

      【讨论】:

      • 您是否有不支持“新”运算符的来源?我在草图中使用它,它工作得很好,编译时没有任何警告。
      • @ChrisR 很有趣。我参考了答案顶部链接的 avrlibc 常见问题解答。该常见问题解答表明new 限制可能已修复,所以它可能已经修复,而常见问题解答现在已过时?
      • 我猜这个常见问题解答已经过时了。有一个关于如何为库使用类的 Arduino 教程 (arduino.cc/en/Hacking/LibraryTutorial),我在当前草图中使用抽象类和虚函数。
      • @ChrisR 只要实例是在全局或堆栈上创建的(即不在堆上使用new - 这是LibraryTutorial 所做的),类总是可以的。并且引用的常见问题解答说虚函数也可以。
      • 过时的答案,当前的 Arduino 支持新建/删除、模板、C++ 类。
      【解决方案3】:

      功能的可用性不受平台限制,而是受您使用的编译器的限制。

      我会检查您的编译器文档以了解支持哪些语言功能。

      【讨论】:

      • 不完全...受限硬件在决定是否应支持异常方面发挥着重要作用。
      • 这不是硬件的限制。这是对编译器的约束,因为我们认为最好不要使硬件过载(硬件理论上可以支持它,但我们不想使用所需的资源来这样做)。
      • 对编译器的任何约束都可能对正在编译的程序施加进一步的约束。硬件理论上可以支持它,但前提是您自己的资源需求不超过一定的限制。由于问题的性质,这个限制非常不稳定(随着您的程序复杂性/要求而变化),因此基于此来打开/关闭异常是不明智的(将导致主要的代码流失)。显然,存在一些硬件 X,它们甚至无法单独支持基本的异常处理,这使得您的“编译器约束”论点没有实际意义。
      • 你没有抓住重点。这不是硬件约束,而是编译器施加的约束。另外你有没有提到不能支持异常的硬件?
      • 我并不是想变得困难,但我真的很想了解这是一个编译器问题。我要说的是,编译器首先受到限制是有原因的吗?是不是因为硬件几乎无法应付应用程序逻辑而没有异常并且添加异常只会杀死它(很可能)?
      【解决方案4】:

      Comeau computing 有一个 C++ 到 C 编译器,它支持所有 C++ 特性。不只是虚函数或异常,还有导出。您需要调用 Comeau 以使其以 Arduino 语言为目标,但应该不会太难。

      【讨论】:

        【解决方案5】:

        文档说:

        Arduino 语言基于 C/C++,支持所有标准 C 结构和一些 C++ 特性。

        它没有说明我能找到的虚函数。

        我尝试了一个简单的程序,它编译得很好。不过,我还没有在 Arduino 硬件上测试过它。

        编辑:我也没有测试异常。

        【讨论】:

          【解决方案6】:

          我将 g++ 与 this Makefile 一起使用,并从 this code 开始。 C++ 浪费了一些空间。但是protothreads太酷了,不能用。

          【讨论】:

          • Makefile 不再可用
          猜你喜欢
          • 2013-01-19
          • 2010-09-14
          • 1970-01-01
          • 1970-01-01
          • 2021-09-03
          • 1970-01-01
          • 1970-01-01
          • 2011-09-03
          • 1970-01-01
          相关资源
          最近更新 更多