3

I am mindblown by this small code:

#include <stdio.h>

    int main()
    {
        int limit = 0;
        scanf("%d", &limit);
        int y[limit];
        
        for (int i = 0; i<limit; i++ ) {
            y[i] = i;
        }
        
        for (int i = 0; i < limit; i++) {
            printf("%d ", y[i]); 
        }
    
        return 0;
    }

How on earth this program is not segment-faulting as limit (size of the array) is assigned at runtime only?

Anything recently changed in C? This code shouldn't work in my understanding.

4
  • 7
    VLAs have been a standard-compliant feature in C since 1999 Commented Feb 22, 2022 at 10:18
  • 1
    It's called a variable-length array, and the way you're using it here is pretty dangerous. Note that it's not "static" as implied by your question. It's just an array on the stack, whose size is reserved using whatever value limit has at the point of definition -- hopefully that isn't negative, very large, or undefined due to assumptions about user input. Commented Feb 22, 2022 at 10:19
  • 2
    VLAs became optional since 2011 :) ... C11 6.10.8.3 Commented Feb 22, 2022 at 10:23
  • 1
    Why do you think it should segfault? You never exceed array bounds here (provided scanf succeeds). The only problem is when limit is very large (>10000 or so depending on your platform), the program might crash because of a stack overflow as variable length arrays (VLAs) are usually stored on the stack. Another thing that can happen is that your code cannot by compiled if the compiler doesn't implement VLAs. Commented Feb 22, 2022 at 10:28

2 Answers 2

7

int y[limit]; is a Variable Length Array (or VLA for short) and was added in C99. If supported, it allocates the array on the stack (on systems having a stack). It's similar to using the machine- and compiler-dependent alloca function (which is called _alloca in MSVC):

Example:

#include <alloca.h>
#include <stdio.h>

int main()
{
    int limit = 0;
    if(scanf("%d", &limit) != 1 || limit < 1) return 1;

    int* y = alloca(limit * sizeof *y); // instead of a VLA

    for (int i = 0; i<limit; i++ ) {
        y[i] = i;
    }

    for (int i = 0; i < limit; i++) {
        printf("%d ", y[i]);
    }
} // the memory allocated by alloca is here free'd automatically

Note that VLA:s are optional since C11, so not all C compilers support it. MSVC for example does not.

Sign up to request clarification or add additional context in comments.

Comments

-2

This doesnt compile in visual studio because limit "Error C2131 expression did not evaluate to a constant"

If you make limit a constexpr though then the compiler will not mind because youre telling it it wont change. You cant use 0 though as setting an array to a constant size length zero is nonsence.

What compiler does this run on for you ?

3 Comments

There is no constexpr in C (and const int wouldn't work either if the compiler doesn't support VLAs). And MSVC is known not to support VLAs (yet still being C11 compliant because VLAs have been made optional in that version of the standard)
This is not an answer and should be a question on its own. It could reference this question, however.
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.