将 C++14 与 AVR-GCC (Arduino Uno) 结合使用

Using C++14 with AVR-GCC (Arduino Uno)

我正在尝试让我的 Arduino 代码使用 -std=c++14 而不是默认的 -std=gnu++11 进行编译。为此,我添加到我的 platformio.ini:

build_flags = -std=c++14
build_unflags = -std=gnu++11

但是,当我尝试编译时,出现以下链接器错误:

<artificial>:(.text+0x20a4): undefined reference to `operator delete(void*, unsigned int)'

(多次)

我好像缺少 delete 运算符。我发现了一些关于手动添加它的线索,这在过去似乎是 Arduino 所必需的。然而,这不应该再这样了,使用默认的 gnu++11 我没有这个问题。为什么 c++14(以及后来的标准及其 GNU 扩展)而不是默认的 gnu++11

我只有avr-gcc(Arduino Uno)有这个问题,arm-none-eabi-g++(Teensy)没有这个问题。

经过一番搜索后发现,从 C++14 开始的 C++ 定义了两个额外的 delete 运算符:

void operator delete ( void* ptr, std::size_t sz ) noexcept; (5) (since C++14)
void operator delete[]( void* ptr, std::size_t sz ) noexcept; (6) (since C++14)

5-6) Called instead of (1-2) if a user-defined replacement is provided, except that it's unspecified whether (1-2) or (5-6) is called when deleting objects of incomplete type and arrays of non-class and trivially-destructible class types. A memory allocator can use the given size to be more efficient. The standard library implementations are identical to (1-2).

(来自 https://en.cppreference.com/w/cpp/memory/new/operator_delete

ArduinoCore-avr's source,其实有这些,定义如下:

#if __cplusplus >= 201402L
void operator delete(void* ptr, std::size_t size) noexcept {
  operator delete(ptr);
}
void operator delete[](void * ptr, std::size_t size) noexcept {
  operator delete[](ptr);
}
#endif // __cplusplus >= 201402L

但是,ArduinoCore-avr 似乎已经有一段时间没有新版本了,上一个版本早于这个(相对较新的)代码。

在我自己的代码中添加上面的定义后,它编译:)