我正在为我的大学进行一个高级小组项目,而在尝试使我的代码生效时遇到了一个重大障碍。

我们为8位Atmel微 Controller 提供的编译器不支持new或delete运算符,并且不支持C++ STL。我可以用C编程,但是我必须实现以前从未做过的A *算法。当我最初尝试C时,我很快意识到我以前从未做过纯C。尝试使用结构和函数为对象建模会减慢我的速度,因为我已经习惯了更加简洁的C++语法。

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

为了克服它们并仍然使用C++,我考虑了以下可能性。
1)不分配任何东西,仅使用模板在堆栈上生成固定的数组。
2)一旦我为对象分配了空间,就分配并找到一些技巧来调用对象的构造函数。由于new不是运算符,因此不能选择new放置。
3)只需使用C并将其吸收,它是一个微 Controller ,为什么我会花哨?
4)找到一个更好的编译器,可能会花费$$$。

第二种选择是最难的,但是就我如何编写此代码而言,它将获得最大的返回。但是,我想如果我弄错了,调试它可能会很痛苦。我正在考虑在堆栈上创建对象,将其位复制到分配的空间中,然后将对象中的位清零,以使其不调用其析构函数。为此,我将直接使用无符号char指针和sizeof运算符访问位以获取字节数。

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

最佳答案

仅作记录,将对象中的位清零不会影响析构函数是否被调用(除非编译器具有启用此行为的特殊功能)。只需在析构函数中编写一些日志记录语句即可进行测试。

构建程序不分配任何内容可能是系统设计的方式。我以前没有使用过嵌入式系统,但是我读过一些经验丰富的嵌入式商店,它们不鼓励使用动态内存,因为运行时环境中的动态内存很少。

但是,如果必须,您仍然可以使用新的展示位置。如果您没有<new> header ,则以下是我的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() { }

将其粘贴到每个使用放置新位置/删除位置的源文件包含的头文件中的某个位置。

测试此文件的样本文件:
#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)。

现在,如果您想将其与malloc结合使用(如果您的平台提供了此功能),则可以执行以下操作:
#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;
}

这使您可以使用熟悉的标准new/delete,而无需使用libstdc++

祝你好运!

10-04 17:42