Неопределенный оператор delete
Код
class Test {};
void setup() {
Test * t = new Test();
delete t;
}
Компилирую скетч для Ардуино на cmake + avr. На строчке с delete Получаю ошибку
undefined reference to `operator delete(void*, unsigned int)'
это что такое? Зачем компилятор (а вернее линковщик) требует переопределения оператора delete да еще и с такими параметрами?
Содержимое CMakeList.txt
cmake_minimum_required(VERSION 2.8.4)
set(CMAKE_TOOLCHAIN_FILE ${CMAKE_SOURCE_DIR}/cmake/ArduinoToolchain.cmake)
set(CMAKE_CXX_STANDARD 17)
set(PROJECT_NAME Controller)
set(${PROJECT_NAME}_BOARD uno)
# set(ARDUINO_CPU)
project(${PROJECT_NAME})
include_directories(${PROJECT_SOURCE_DIR})
file(GLOB SRC_FILES ${PROJECT_SOURCE_DIR}/*.cpp)
file(GLOB HDR_FILES ${PROJECT_SOURCE_DIR}/*.h)
set(${PROJECT_NAME}_SRCS ${SRC_FILES})
set(${PROJECT_NAME}_HDRS ${HDR_FILES})
set(${PROJECT_NAME}_PORT COM4)
generate_arduino_firmware(${PROJECT_NAME}
SRCS ${${PROJECT_NAME}_SRCS}
HDRS ${${PROJECT_NAME}_HDRS}
)
print_board_list()
print_programmer_list()
Ответы (2 шт):
Это происходит, так как avr-g++ не поддерживает libstdc++
Из avr-libc FAQ
Can I use C++ on the AVR?
Basically yes, C++ is supported (assuming your compiler has been configured and compiled to support it, of course). Source files ending in .cc, .cpp or .C will automatically cause the compiler frontend to invoke the C++ compiler. Alternatively, the C++ compiler could be explicitly called by the name avr-c++.
However, there's currently no support for libstdc++, the standard support library needed for a complete C++ implementation. This imposes a number of restrictions on the C++ programs that can be compiled. Among them are:
- Obviously, none of the C++ related standard functions, classes, and template classes are available.
- The operators new and delete are not implemented, attempting to use them will cause the linker to complain about undefined external references. (This could perhaps be fixed.)
- Some of the supplied include files are not C++ safe, i. e. they need to be wrapped into
extern "C" { . . . }(This could certainly be fixed, too.)- Exceptions are not supported. Since exceptions are enabled by default in the C++ frontend, they explicitly need to be turned off using -fno-exceptions in the compiler options. Failing this, the linker will complain about an undefined external reference to
__gxx_personality_sj0. Constructors and destructors are supported though, including global ones.When programming C++ in space- and runtime-sensitive environments like microcontrollers, extra care should be taken to avoid unwanted side effects of the C++ calling conventions like implied copy constructors that could be called upon function invocation etc. These things could easily add up into a considerable amount of time and program memory wasted. Thus, casual inspection of the generated assembler code (using the -S compiler option) seems to be warranted.
Библиотека arduino содержит реализацию new/delete(файлы new.cpp и new.h), но используемый Вами скрипт ArduinoToolchain.cmake не подключает их при сборке библиотеки arduino core
Вы можете попробовать другую реализацию Arduino Toolchain для cmake
Например, https://github.com/a9183756-gh/Arduino-CMake-Toolchain
Пример файл проекта для cmake:
cmake_minimum_required(VERSION 3.10)
project(test_uno CXX)
add_executable(test_uno main.cpp)
target_link_arduino_libraries(test_uno PRIVATE core)
target_enable_arduino_upload(test_uno)
Параметры cmake:
cmake \
-DCMAKE_TOOLCHAIN_FILE=/path/to/Arduino-toolchain.cmake \
-DARDUINO_BOARD="avr.uno" \
/path/to/sources.dir
//main.cpp
#include <Arduino.h>
class Test {};
void setup() {
Test * t = new Test();
delete t;
}
void loop() {}
В C++14 появился перегруженный оператор delete
void operator delete ( void* ptr, std::size_t sz ) noexcept;
который удаляет память указанного размера. В ардуиновской библиотеке определены только такие варианты
void * operator new(size_t size);
void * operator new[](size_t size);
void * operator new(size_t size, void * ptr) noexcept;
void operator delete(void * ptr);
void operator delete[](void * ptr);
Я понизил в CMakeLists.txt версию с++ до 11
set(CMAKE_CXX_STANDARD 11)
и все стало компилироваться