AVR-GCC(Arduino Uno)使用C++14编译出现operator delete未定义错误
问题根因
- C14标准新增了带长度参数的
operator delete(void*, std::size_t)(也叫sized deallocation)重载,GCC从C14及更高版本开始默认启用该特性,编译时会自动生成对该重载的调用 - Arduino Uno使用的AVR架构配套的avr-libc运行时库,出于8位单片机极小的闪存容量优化考虑,始终没有内置该重载的实现,仅提供了原始的无长度参数的
operator delete(void*) - 默认使用
-std=gnu++11时,GCC不会启用sized deallocation特性,仅生成对原始delete运算符的调用,因此不会出现链接错误;切换到C++14及更高版本后,编译器生成的新重载符号在avr-libc中不存在,就会触发undefined reference报错 - 而Teensy使用的ARM架构配套的arm-none-eabi-g运行时库实现了完整的C标准运算符,因此不存在该问题
两种解决方案
方案1:禁用sized deallocation特性(最简便)
在platformio.ini的build_flags中添加编译参数即可,无需修改业务代码:
build_flags = -std=c++14 -fno-sized-deallocation build_unflags = -std=gnu++11
该参数会强制GCC即使在C++14及更高标准下,也仅生成对原始无长度参数delete运算符的调用,和gnu++11的行为一致。
方案2:手动实现缺失的运算符重载
在项目全局代码(比如主文件开头、自定义头文件全局位置)添加以下实现即可:
#include <stdlib.h> // 实现缺失的sized delete重载 void operator delete(void* ptr, unsigned int sz) noexcept { free(ptr); } // 若出现delete[]的相关报错,补充以下实现 void operator delete[](void* ptr, unsigned int sz) noexcept { free(ptr); }
内容的提问来源于stack exchange,提问作者Compizfox
相关产品推荐
相关产品推荐

