Search code examples
c++embeddedplacement-new

Placement new for MCU register abstraction proposed by Meyers


I just tried to use a placement new operator as suggested by Scott Meyers in "Effectice C++ in an Embedded Environment".

    DefaultMcuType::PortRegister* p = new(reinterpret_cast<void*>(0x05)) DefaultMcuType::PortRegister;

Then I get the follwoing errors:

register.cc: In function 'int main()':
register.cc:30:90: error: no matching function for call to 'operator     new(sizetype, void*)'
 DefaultMcuType::PortRegister* p = new(reinterpret_cast<void*>(0x05))  DefaultMcuType::PortRegister;
                                                                                        ^~~~~~~~~~~~
<built-in>: note: candidate: void* operator new(unsigned int)
<built-in>: note:   candidate expects 1 argument, 2 provided
<built-in>: note: candidate: void* operator new(unsigned int,  std::align_val_t)
<built-in>: note:   no known conversion for argument 2 from 'void*' to  'std::align_val_t'
register.cc:30:35: warning: unused variable 'p' [-Wunused-variable]
 DefaultMcuType::PortRegister* p = new(reinterpret_cast<void*>(0x05))    DefaultMcuType::PortRegister;
                               ^

I really can't figure out what I am doing wrong.


Solution

  • Placement new is an operator function. Your specific one should be defined as

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

    in the header file <new>.

    Using #include <new> should resolve your problem.

    For an example see here: https://godbolt.org/g/iKatox

    More information about the new operators can be found here: http://en.cppreference.com/w/cpp/memory/new/operator_new


    Update:

    If you don't have access to placement new you might define it yourself. I used the VC++14 version as a template for this:

    #include <stdlib.h> //for std::size_t
    inline void* operator new(std::size_t size, void* ptr)
    {
      (void)size;//unused
      return ptr;
    }
    
    inline void operator delete(void*, void*)
    {
      return;
    }
    

    You can compare both versions generating the same assembly code: https://godbolt.org/g/6UjER9