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

查看:130
本文介绍了当您的嵌入式编译器没有运算符新增或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.

我们编译器对于我们的8位Atmel微控制器不支持新的或删除的操作符,它不支持C ++ STL。我可以用C编程,但是我必须实现一个我以前从未做过的A *算法。虽然我最初尝试过C,但我很快意识到,我从来没有做过纯C。尝试使用结构体和函数对对象进行建模正在使我失望,因为我习惯了更清晰的C ++语法。

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.

无论如何,我的编译器缺点的确切措辞可以是在这里找到: http://www.nongnu.org/avr- libc / user-manual / FAQ.html#faq_cplusplus

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

为了克服它们,仍然使用C ++,我考虑了以下几种可能性。
1)不要分配任何东西,只需使用模板在堆栈上生成固定数组。
2)一旦我们为它们分配了空间,分配并找到一些hack来调用对象的构造函数。安置新的不是一个选择,因为新的不是运营商。
3)只需使用C并吸吮它,它的微控制器为什么我喜欢?
4)找到一个更好的编译器,这可能会花费$ $$$。

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 $$$.

第二个选项是最难的,但它将是最大的收益我该怎么写这段代码但是,我想如果我错了,调试可能会是一个巨大的痛苦。我正在考虑在堆栈上创建对象,将它们的位复制到分配的空间中,然后将对象中的位归零,以便不调用其析构函数。为了做到这一点,我将直接使用unsigned char指针和sizeof运算符访问这些位来获取字节数。

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.

这听起来很糟糕,我不知道是否可以工作可靠,但我正在考虑。我知道vtables可能是一个问题,但我不打算有任何vtables,因为它只是一个8位微控制器。

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.

但是,如果必须,您仍然可以使用展示位置新的。如果您没有< new> 标题,请在我的GCC版本上直接显示相关行:

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();
}

在我的GCC版本中,这不使用 libstdc ++ (如果使用 -fno-exceptions )。

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

现在,如果要将其与 malloc (如果您的平台提供)结合起来,那么可以这样做:

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;
}

这允许您使用标准的 code> / 删除您熟悉的,而不需要使用 libstdc ++

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

祝你好运!

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

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