Skip to content
← Prism
Prism
Overview
Features
defer orelse zeroinit raw bounds-check auto-unreachable auto-static check
C in practice
Overview goto skips init tag namespace struct padding strict aliasing char signedness signed overflow VLAs segfaults
Spec Draft Releases Blog
GitHub ↗

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.

Before: hidden memcpy every call
void process(int x) {
    const int lut[4] = {10, 20, 30, 40};
    // ^ compiler emits memcpy from rodata → stack
    use(lut[x & 3]);
}
After: single copy in rodata, zero runtime cost
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:

#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.c

There 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).

#Spec Reference

auto-static: Prism Spec §6.9