当您的嵌入式编译器不支持 operator new 或 STL 时,您如何使用 C++? [英] How can you do C++ when your embedded compiler doesn't have operator new or STL support?

查看:29
本文介绍了当您的嵌入式编译器不支持 operator new 或 STL 时,您如何使用 C++?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

I am working on a group senior project for my university and I have run into a major hurdle in trying to get my code to work.

The compiler that we have for our 8 bit Atmel microcontroller does not support the new or delete operators, and it does not support the C++ STL. I could program it in C, but I have to implement an A* algorithm which I have never done before. While I have tried C initially I soon realized that I never did pure C before. Trying to model objects with structs and functions is slowing me down since I am so used to the much cleaner C++ syntax.

Regardless, the exact wording for my compilers shortcomings can be found here: http://www.nongnu.org/avr-libc/user-manual/FAQ.html#faq_cplusplus

To overcome them and still use C++ I have considered the following possibilities. 1) Don't allocate anything, just use templates to generate fixed arrays on the stack. 2) Allocate and find some hack to call the constructor for objects once I have allocated the space for them. Placement new isn't an option since new isn't an operator. 3) Just use C and suck it up, its a microcontroller why am I getting fancy? 4) Find a better compiler which will probably cost $$$.

The second option is the hardest but it would have the biggest pay off in terms of how I can write this code. However, I imagine that debugging it could be a huge pain if I get it wrong. I'm thinking of creating objects on the stack, copying their bits into the allocated space, and then zeroing the bits in the object so it doesn't call its destructor. To do that I would access the bits directly with an unsigned char pointer and the sizeof operator to get the byte count.

That sounds terrible and I don't know if it could work reliably, but I am considering it. I know vtables can be a problem but I don't intend on having any vtables since it is just an 8 bit microcontroller.

解决方案

Just for the record, zeroing the bits in an object won't affect whether the destructor gets called (unless the compiler has a special quirk that enables this behaviour). Just write some logging statements in your destructor to test this out.

Structuring your program not to allocate anything is probably the way the system was designed. I've not worked with embedded systems before, however I have read some experienced embedded shops that discourage use of dynamic memory because the runtime environment has scarce amounts of it.


However, if you must, you can still use placement new. If you don't have the <new> header, here are the relevant lines directly from it on my version of GCC:

// Default placement versions of operator new.
inline void* operator new(std::size_t, void* __p) throw() { return __p; }
inline void* operator new[](std::size_t, void* __p) throw() { return __p; }

// Default placement versions of operator delete.
inline void  operator delete  (void*, void*) throw() { }
inline void  operator delete[](void*, void*) throw() { }

Stick that somewhere in a header file included by every source file that uses placement new/delete.

Sample file that tests this:

#include <cstdio>
#include <new>

int
main(int argc, char** argv)
{
    typedef char const* cstr;
    char foobar[16];
    cstr* str = new (&foobar) cstr(argc > 1 ? argv[1] : "Hello, world!");
    std::puts(*str);
    str->~cstr();
}

On my version of GCC, this does not use libstdc++ at all (if -fno-exceptions is used).


Now, if you want to combine that with malloc (if your platform provides this), then you can do this:

#include <cstdio>
#include <cstdlib>

inline void* operator new  (std::size_t n) {return std::malloc(n);}
inline void* operator new[](std::size_t n) {return std::malloc(n);}
inline void  operator delete  (void* p) {std::free(p);}
inline void  operator delete[](void* p) {std::free(p);}

int
main(int argc, char** argv)
{
    typedef char const* cstr;
    cstr* str = new cstr(argc > 1 ? argv[1] : "Hello, world!");
    std::puts(*str);
    delete str;
}

This allows you to use the standard new/delete that you're familiar with, without requiring use of libstdc++.

Good luck!

这篇关于当您的嵌入式编译器不支持 operator new 或 STL 时,您如何使用 C++?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆