C++ 在编译时强制执行静态存储
我有一个结构,我想强制静态存储。这是DSP上的向量类型,用户在堆栈上意外声明它是一种常见错误,会导致堆栈溢出、性能问题或两者兼而有之。据我所知,这是不可能的,但我很好奇是否有其他人知道得更好 示例用例:C++ 在编译时强制执行静态存储,c++,c,C++,C,我有一个结构,我想强制静态存储。这是DSP上的向量类型,用户在堆栈上意外声明它是一种常见错误,会导致堆栈溢出、性能问题或两者兼而有之。据我所知,这是不可能的,但我很好奇是否有其他人知道得更好 示例用例: static Vector64 v1; // OK static Vector64 v2; // OK static Vector64 result; // OK result = v1 * v2; // OK Vector64 v3; // I would like this to gi
static Vector64 v1; // OK
static Vector64 v2; // OK
static Vector64 result; // OK
result = v1 * v2; // OK
Vector64 v3; // I would like this to give a compile-time error
Vector64 v4;
result = v3 * v4;
我的编译器是Clang/LLVM 3.2,编译器特定的属性是公平的。如果你在C上编程,你会遇到问题。用C++进行工作。我从未使用过那个编译器,但这两种语言在这方面有很大的不同。检查一下你的编译器。因为C没有类,我几乎排除了这一点
一般来说,在C++中,当定义一个类时,不能控制该类型的对象是否定义为“代码”>堆栈上的静态< <代码> >,在堆上,<代码> const >或“<代码> const < /C> >,以数组或另一个类的成员。这些选项由类的用户决定
有一些技巧可以让它远离堆(例如玩操作符new
),或者只在堆上(例如使用生成器模式),但这不是您想要的
我很想看看这是怎么可能的,但在此之前,我很确定您不能。如果您愿意接受运行时错误并深入实现,并且如果您的DSP具有合适的地址布局,您可以简单地在Vector64的默认构造函数中插入检查
此的位置
如果您提前知道地址空间,最安全的方法(语言方面)就是简单地比较堆栈的绝对位置
struct Vector64 {
Vector64() { assert( reinterpret_cast<uintptr_t>(this) < STACK_START ); }
};
结构向量64{
Vector64(){assert(reinterpret_cast(this)
风险更高但更灵活的定义可能如下所示:
__attribute__((noinline)) Vector64() {
int test;
assert( less<void*>()(this, &test) );
}
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu((noinline))向量64(){
智力测验;
断言(less()(this,&test));
}
其中需要\uuuu属性(noinline))
来防止clang在Vector64对象之前排序测试的分配(或在别处简单地定义它)。好的一面是,重新排序优化不会导致该断言抛出假阳性,只能默默地失败std::less
在这里也很重要,因为与不同,我将两者都标记为std::less,因为我可以自如地使用任何一种语言的解决方案。我们通常使用C++ 11,但是我们从各种源构建任何单个项目(ASM/C/C++),您能演示一下这将如何与C++一起工作?如果这是可能的,那么这不是直观的,而且会非常困难。@Glentitelbaum为什么你认为这是可能的?恐怕不是,但我想证明我错了@SamCristall-我不知道这怎么可能,但我不想排除有人比我聪明,所以我说如果。这个答案说:“用C++来工作”,所以我想看看如何。GlennTeitelbaum Ahh,阅读理解失败了。进行!我知道(使用C++时)如何只允许动态存储(防止静态和自动),或防止动态存储(只允许静态和自动),但我不相信您可以区分静态存储持续时间和自动存储持续时间。此外,发出运行时警告也不会非常困难(请仅在调试模式下打开)。您可以使用自定义堆分配吗?您可以将Vector64
实例化隐藏在工厂后面,并通过使用自定义分配器强制完全控制堆存储(如果需要,请对齐).@BenVoigt您对该运行时警告有特殊的实现吗?我可以处理它。@很遗憾,平台上没有堆,但我正在考虑专门为此目的滚动我自己的简单分配器。您可以重写类上的运算符new并将其声明为private。如果有错误,这将生成编译错误任何堆分配尝试。