在编译时强制执行静态存储

时间:2014-01-07 00:05:08

标签: 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 give a compile-time error
Vector64 v4;
result = v3 * v4;

我的编译器是Clang / LLVM 3.2,特定于编译器的属性是合理的游戏。

3 个答案:

答案 0 :(得分:2)

由于C没有课程,我几乎要排除这一点。

通常,在C ++中定义类时,无法控制是否在堆栈上,堆上,staticconstconst ally定义该类型的对象。在一个数组或另一个类的成员中。这些是对班级用户的选择。

有一些技巧可以让它远离堆(例如,使用operator new),或者仅在堆上(例如使用生成器模式),但这不是你想要的 < / p>

我很想知道这是怎么可能的,但在此之前,我很确定你不能。

答案 1 :(得分:2)

如果您愿意解决运行时错误并深入了解实施水域,并且如果您的DSP具有合适的地址布局,您可以简单地插入检查{的位置Vector64的默认构造函数中的{1}}。

如果您提前知道地址空间,最安全的事情(语言方面)就是简单地比较堆栈的绝对位置。

this

风险更高但更灵活的定义可能如下所示:

struct Vector64 {
    Vector64() { assert( reinterpret_cast<uintptr_t>(this) < STACK_START ); }
};

需要__attribute__((noinline)) Vector64() { int test; assert( less<void*>()(this, &test) ); } 来防止clang在Vector64对象之前排序__attribute__((noinline))(或者只是在别处定义它)。从好的方面来说,重新排序优化不会导致这个断言产生误报,只能无声地失败。 test在这里也很重要,因为与std::less不同,它明确允许在不同对象的地址之间进行比较。

这种方法非常讨厌,但是通过干预构造,你可以通过确保不再构造堆栈溢出来防止堆栈溢出。

答案 2 :(得分:-2)

如果您使用C编程,那么您将遇到问题。使用C ++它应该工作。我从未使用过那个编译器,但两种语言在这方面都有很大的不同。检查你的编译器。