0

Note: I have seen In C, why can't a const variable be used as an array size initializer? already, but this doesn't quite answer my question (or I am not understanding it fully).

This works:

int main() {
    const long COUNT = 1048106;
    int nums[COUNT];
    return 0;
}

This crashes:

int main() {
    const long COUNT = 1048106000;
    int nums[COUNT];
    return 0;
}

I have read that this is actually an inappropriate use of const to begin with (since it means read-only, not evaluated at compile time).

So I am happy to use #define or whatnot instead, but still, it bothers me why this works for some lengths but not but not any higher.

tacos_tacos_tacos
  • 10,277
  • 11
  • 73
  • 126
  • 1
    A typical Unix program has 8 MiB of stack; a typical Windows program has 1 MiB of stack. Your big size array blows the stack limits out of the water. Either use a global variable or use dynamic memory allocation. Remember: the stack is finite and small (and error recovery from a blown stack is problematic at best). (The first version allocates about 4 MiB on stack; that suggests you're running on a Unix-like system, Linuex for example. The second version tries to allocate 4 GiB or so on stack — that's not gonna fly anywhere normal.) – Jonathan Leffler Nov 25 '18 at 08:16
  • IMO, there use of a VLA has no particular relevance; what matters is the size of the array, not whether it is a VLA or not. – Jonathan Leffler Nov 25 '18 at 08:19

1 Answers1

3

Both your array declarations are in fact variable length array declarations. COUNT is not a constant expression in C, despite being const.

But regardless, the bigger size simply exceeds your implementation's limits, overflowing the call stack where those locals are usually allocated. Though I suspect this behavior will go away should you compile with optimizations. A compiler can easily deduce that nums isn't used in your snippet, and remove it entirely.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
  • Ok, awesome. So this is a stack overflow because the stack doesn't have enough space to address that big an array? – tacos_tacos_tacos Nov 25 '18 at 07:39
  • @tacos_tacos_tacos - Yup. You found its limit. Though it's worth noting the most compilers will let you set the size of the call stack for the generated program, via compilation flags. – StoryTeller - Unslander Monica Nov 25 '18 at 07:41
  • I don't think the behaviour will go away. Even if it is a const.length array, it's still on the stack. – glglgl Nov 25 '18 at 07:43
  • @glglgl - Compilers are free to optimize as they please under the as-if rule. And if a variable isn't used, the program can be successfully translated as-if the variable was never declared. – StoryTeller - Unslander Monica Nov 25 '18 at 07:44
  • 1
    The fact that it is a VLA is tangential to the crash. Changing the numbers to enumeration constants so it isn't a VLA would still lead to a crash — because the stack size on Unix is normally limited to about 8 MiB and on Windows to about 1 MiB, and the first code tries to allocate about 4 MiB and the second about 4 GiB. That the first works suggests the OP is running on a Unix-ish system (Linux, macOS, BSD, Solaris, AIX, HP-UX, …). – Jonathan Leffler Nov 25 '18 at 08:21
  • @Jonathan - Fine, I rephrased to make the two points stand apart. Anyway, this is all still subject to optimizations. Under O1 neither snippet crashes. – StoryTeller - Unslander Monica Nov 25 '18 at 08:26
  • @JonathanLeffler That's exactly my point. OTOH, if it isn't used, it indeed can be optimized as well – again, no matter if it is VLA or not. – glglgl Nov 25 '18 at 11:35