Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/66.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 在编译时强制执行静态存储_C++_C - Fatal编程技术网

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

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

我有一个结构,我想强制静态存储。这是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,编译器特定的属性是公平的。

如果你在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。如果有错误,这将生成编译错误任何堆分配尝试。