Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions cpu/avr8_common/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ config CPU_ARCH_AVR8
select MODULE_MALLOC_THREAD_SAFE if TEST_KCONFIG
# static C++ constructors need guards for thread safe initialization
select MODULE_CXX_CTOR_GUARDS if MODULE_CPP
# new and delete operators needed
select MODULE_CPP_NEW_DELETE if MODULE_CPP

## Common CPU symbols
config CPU_ARCH
Expand Down
5 changes: 5 additions & 0 deletions cpu/avr8_common/Makefile.dep
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,8 @@ endif
ifneq (,$(filter cpp,$(FEATURES_USED)))
USEMODULE += cxx_ctor_guards
endif

# new and delete operators needed
ifneq (,$(filter cpp,$(FEATURES_USED)))
USEMODULE += cpp_new_delete
endif
1 change: 1 addition & 0 deletions sys/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ rsource "checksum/Kconfig"
rsource "color/Kconfig"
rsource "crypto/Kconfig"
rsource "congure/Kconfig"
rsource "cpp_new_delete/Kconfig"
rsource "cxx_ctor_guards/Kconfig"
rsource "div/Kconfig"
rsource "embunit/Kconfig"
Expand Down
17 changes: 17 additions & 0 deletions sys/cpp_new_delete/Kconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Copyright (C) 2021 Gunar Schorcht
#
# This file is subject to the terms and conditions of the GNU Lesser
# General Public License v2.1. See the file LICENSE in the top level
# directory for more details.
#

config MODULE_CPP_NEW_DELETE
bool
depends on TEST_KCONFIG
depends on MODULE_CPP
help
On some platforms libstdc++ is not used or not available, like on
the AVR. Such platforms can use this module to implement the C++
new and delete operators using malloc and free respectively. However,
to be thread-safe, a thread-safe implementation of malloc and free
must be present.
3 changes: 3 additions & 0 deletions sys/cpp_new_delete/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include $(RIOTBASE)/Makefile.base

CXXFLAGS += -std=c++11
22 changes: 22 additions & 0 deletions sys/cpp_new_delete/doc.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/**
@defgroup sys_cpp_new_delete C++ new and delete operator module
@ingroup sys
@brief This module provides the `new` and `delete` operators for platforms
that do not use `libstdc++`.
@warning This module is automatically selected, if needed. Never add it
manually.

# Background

On some platforms `libstdc++` is not used or not available, like on the AVR.
Such platforms can use this module to implement the C++ `new` and `delete`
operators using `malloc` and `free` respectively. However, to be thread-safe,
a thread-safe implementation of `malloc` and `free` must be present.

# Usage

This module is intended to be use by platforms that not providing the required
operators. Hence, application developers and users should never select this
module by hand.

*/
40 changes: 40 additions & 0 deletions sys/cpp_new_delete/new_delete.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) 2014 Arduino. All right reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/

#include <stdlib.h>

void *operator new(size_t size) {
return malloc(size);
}

void *operator new[](size_t size) {
return malloc(size);
}

void *operator new(size_t size, void *ptr) noexcept {
(void)size;
return ptr;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't quite get this one. I cannot find an API doc, but the arguments do not seem to make much sense unless this expected to behave somewhat like realloc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

According to https://www.cplusplus.com/reference/new/operator%20new/

void* operator new (std::size_t size, void* ptr) noexcept;

is the placement function which simply returns ptr and doesn't allocate storage:

ptr 
       A pointer to an already-allocated memory block of the proper size.
       If called by a new-expression, the object is initialized (or constructed) at this location.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The counterpart is

void operator delete (void* ptr, void* voidptr2) noexcept;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Found an good example how it could be used at cppreference.com

// within any block scope...
{
    alignas(T) unsigned char buf[sizeof(T)];
    // Statically allocate the storage with automatic storage duration
    // which is large enough for any object of type `T`.
    T* tptr = new(buf) T; // Construct a `T` object, placing it directly into your 
                          // pre-allocated storage at memory address `buf`.
    tptr->~T();           // You must **manually** call the object's destructor
                          // if its side effects is depended by the program.
}                         // Leaving this block scope automatically deallocates `buf`.


void operator delete(void *ptr) {
free(ptr);
}

void operator delete[](void *ptr) {
free(ptr);
}