我正在为我的大学进行一个高级小组项目,而在尝试使我的代码生效时遇到了一个重大障碍。
我们为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++
。祝你好运!