【问题标题】:How to prevent a virtual method from always being compiled?如何防止虚拟方法总是被编译?
【发布时间】:2014-10-17 22:58:58
【问题描述】:

在处理 Arduino 库时,我遇到了一个有趣的编译问题。所有类中的所有虚拟方法都被编译......总是。即使该类从未被构建甚至被提及。

重现此问题的示例 Arduino 代码:

class BaseClass {
  virtual void method();
};

void BaseClass::method() {
  Serial.println("This should not be compiled at all...");
}

void setup() {
}

void loop() {
}

省略 BaseClass 会导致最终的二进制文件为 670 字节。包括它,虽然从不使用该类,但代码大小为 3.354 字节。

对于一个包含许多根本不会经常使用的类的库,所有这些类都包含一个虚拟的update() 例程,这种行为是不可接受的。到目前为止,我发现的唯一解决方案是强制用户包含他希望使用的组件的头文件。不过,我最好让库保持简单,而不要求用户这样做。

是否有一个 AVR 方法属性可以告诉编译器仅在某个地方构造类时才编译虚拟方法?或者,是否有编译器选项可以让我优化这些未使用的虚拟方法?

使用 ATMEGA2560 AVR 和 G++ 编译器。 Arduino 传递的当前编译器选项:

C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega2560 -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=106 -IC:\Program Files (x86)\Arduino\hardware\arduino\cores\arduino -IC:\Program Files (x86)\Arduino\hardware\arduino\variants\mega

【问题讨论】:

  • 也许-fvtable-gc 是你想要的? (Source) 您可能需要额外的选项来实际抛弃方法实现。查看链接。
  • 看起来这是解决方案,一旦我找到一种方法来更改 Arduino 软件中的编译器选项,我就可以确定它是否有效。

标签: c++ class compilation arduino virtual-functions


【解决方案1】:

使用-fno-implicit-templates 您可能会立即解决问题,您必须明确地实例化您确实使用的那些模板。

您的用户必须在所有未实例化模板的完整实现中包含一个标头,并为他们使用的模板使用正确的标志/显式实例化。

【讨论】:

  • 将此标记为已接受的答案以将线程标记为已回答。这可能是一个同样可以接受的解决方案,尽管我还没有尝试过。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-30
  • 2020-03-19
  • 1970-01-01
  • 2022-10-15
相关资源
最近更新 更多