auto-static
Promote const arrays to static storage automatically. Eliminates the hidden memcpy that C compilers emit every time a function with a const array initializer is called.
opt-out: prism -fno-auto-static
Overview
In C, a block-scope const array with a literal initializer is stored on the stack. Every function call copies the initializer data from the read-only data segment onto the stack — even though the array never changes. This is a hidden memcpy you didn't ask for.
void process(int x) {
const int lut[4] = {10, 20, 30, 40};
// ^ compiler emits memcpy from rodata → stack
use(lut[x & 3]);
}void process(int x) {
static const int lut[4] = {10, 20, 30, 40};
// ^ Prism promoted this — no memcpy, ever
use(lut[x & 3]);
}Prism detects these arrays and adds static automatically. The semantics are identical — const arrays with literal initializers can never be mutated, so static storage is always correct.
Behavior
When auto-static fires, Prism emits static before the declaration. The array lives in the read-only data segment for the lifetime of the program. Subsequent calls to the function share the same array — no copy, no stack pressure, no cache pollution.
This is purely additive. If the array is already static, Prism leaves it alone. The transformation is invisible at the source level and produces no warnings.
Conditions
Auto-static fires only when all of the following are true:
- Block-scope declaration (not file scope)
- Type is a
constarray - Every initializer token is a literal or enum constant (no variables, no function calls, no expressions)
- No existing storage class:
static,extern,register,constexpr,_Thread_local - No
volatilequalifier - No VLA dimensions
- No
orelsein the declaration - No attributes on the declarator
- Pointer arrays require
conston the array itself:const int * const arr[3]
Examples
// Promoted — pure literal initializer
const int weights[3] = {1, 2, 4};
// Promoted — enum constants qualify as literals
const int masks[4] = {FLAG_A, FLAG_B, FLAG_C, FLAG_D};
// NOT promoted — initializer contains a variable
const int steps[3] = {0, stride, stride * 2};
// NOT promoted — pointer array missing outer const
const char *names[3] = {"foo", "bar", "baz"};
// Promoted — pointer array with correct const
const char * const names[3] = {"foo", "bar", "baz"};Opt-out
Disable globally:
prism -fno-auto-static file.cThere is no per-declaration opt-out — use -fno-auto-static if you need stack semantics for a specific translation unit (e.g. if address identity of the array matters across calls, which is unusual for const arrays).