Forcing static storage at compile time

I have a structure in which I would like to enable static storage. This is a vector type on the DSP, and accidentally declaring it on the stack is a common mistake for users that causes stack overflows, performance problems, or both. As far as I know, this is not possible, but I'm curious if anyone knows even better.

Usage example:

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; 

My compiler is Clang / LLVM 3.2, and compiler-specific attributes are fair game.

+6
source share
3 answers

Since C has no classes, I would almost allow it.

In general, in C ++, when you define a class, you cannot control whether objects of this type will be defined static ally, on the stack, on the heap, const or not const , in an array or a member of another class. These are options available to users of this class.

There are some tricks to keep it from the heap (e.g. playing with operator new ) or only on the heap (e.g. using the generator template), but this is not what you want

I would like to see how this is possible, but until that time I am sure that you cannot.

+2
source

If you are ready to accept a run-time error and penetrate deeply into the implementation water, and if your DSP has a suitable address layout, you can simply insert this location check into the default constructor of Vector64.

If you know the address space in advance, the safest (in terms of language) is simply to compare the absolute position of the stack.

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

A riskier but more flexible definition might look like this:

 __attribute__((noinline)) Vector64() { int test; assert( less<void*>()(this, &test) ); } 

Where __attribute__((noinline)) necessary to prevent clang from ordering the selection of test before the Vector64 object (or just defining it elsewhere). On the bright side, reordering optimization cannot make it claim to throw a false positive, only fail silently. std::less also important here, because unlike < it explicitly allows comparisons between the addresses of different objects.

This approach is rather unpleasant, but by interfering with construction, you have a better chance of preventing stack overflows at runtime, ensuring that they will no longer be built.

+2
source

If you program in C, you will have problems with this. With C ++, it should work. I have never used this compiler, but in these matters both languages ​​are completely different. Check your compiler.

-2
source

All Articles