我试图尝试让我的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)'
(多次)1似乎缺少delete
运算符。我发现了一些关于手动添加它的线程,这在过去的Arduino中似乎是必要的。然而,这不应该是这种情况下,与默认的gnu++11
我没有这个问题。为什么c++14
(以及后来的标准和它们的GNU扩展)没有这个功能,而默认的gnu++11
没有呢?
我只在avr-gcc(用于Arduino Uno)中遇到此问题,使用arm-none-eabi-g++(用于Teensy),此问题不会发生。
经过一番搜索,发现c++从c++ 14起定义了两个额外的delete
操作符:
void operator delete (void* ptr, std::size_t sz) noexcept;(5)(自c++ 14)
void operator delete[](void* ptr, std::size_t) noexcept;(C++14起)
5-6)如果提供了用户定义的替换,则调用(1-2)而不是(1-2),除非在删除不完整类型的对象以及非类和可简单破坏的类类型的数组时调用(1-2)或(5-6)。内存分配器可以使用给定的大小来提高效率。标准库实现与(1-2)相同。
(https://en.cppreference.com/w/cpp/memory/new/operator_delete)查看ArduinoCore-avr的源代码,这些实际上是存在的,并定义如下:
#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了,上一个版本早于这个(相对较新的)代码。
将上面的定义添加到我自己的代码后,它编译:)