auto-staticautomatic static promotion for const arrays in C
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. Compilers emit a hidden memcpy from rodata to the stack on every call.
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. Your source stays unchanged; Prism emits static in the transpiled output.
#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).