10

I just did a experiment yesterday, and find something confusing:

#include <stdio.h>

int main()
{
    int j;
    scanf("%d",&j);
    const int i = j;
    int arr[i];
    return 0;
}

The number j is read from keyboard and it’s used to allocate the array arr on the stack.

The compiler does not even know the size of the array at compile time (initializes j to 0?), but there is no compilation error. How is it possible?

Palec
  • 12,743
  • 8
  • 69
  • 138
user3769509
  • 109
  • 1
  • 1
  • 5
  • 3
    In fact you should clarify why you think the compiler should give an error – m0skit0 Oct 18 '14 at 16:22
  • 6
    Search `[c] VLA` in this site. – BLUEPIXY Oct 18 '14 at 16:24
  • i think you have been studying c89 all this time.. – Haris Oct 18 '14 at 16:26
  • as a sidenote, passing through the additional variable `i` is useless and the code would be fine without. – Jens Gustedt Oct 18 '14 at 16:56
  • as C11 tag has been added, note that C11 introduced VLAs support optional. `__STDC_NO_VLA__` object-like macro is set to `1` if specific implementation does not handle them. – Grzegorz Szpetkowski Oct 18 '14 at 17:26
  • possible duplicate of [Why am I being allowed to use a const qualified variable as an array size in C?](http://stackoverflow.com/questions/16588265/why-am-i-being-allowed-to-use-a-const-qualified-variable-as-an-array-size-in-c) – phuclv Nov 18 '14 at 06:40
  • possible duplicate of [Dynamic arrays in C without malloc?](http://stackoverflow.com/questions/6656731/dynamic-arrays-in-c-without-malloc) – Palec Mar 15 '15 at 19:55

3 Answers3

15

Variable length arrays were added to C99. It's described in the C99 rationale:

6.7.5.2 Array declarators

C99 adds a new array type called a variable length array type. The inability to declare arrays whose size is known only at execution time was often cited as a primary deterrent to using C as a numerical computing language. Adoption of some standard notion of execution time arrays was considered crucial for C’s acceptance in the numerical computing world.

The number of elements specified in the declaration of a variable length array type is a runtime expression. Before C99, this size expression was required to be an integer constant expression.

There is no "dynamic array allocation on the stack". The array size has to be specified at the declaration.

Some compilers, like GCC allow them as an extension in C90 (in GCC, this is equivalent to ansi and C89) mode and C++. In these cases, you will get a warning (-Wpedantic) or an error (-Werror or -pedantic-errors). Consult the documentation for your compiler.

Per @Deduplicator's comment, you seem to have a misconception. Variable length arrays cannot be declared static.

§ 6.7.6.2

10 EXAMPLE 4 All declarations of variably modified (VM) types have to be at either block scope or function prototype scope. Array objects declared with the _Thread_local, static, or extern storage-class specifier cannot have a variable length array (VLA) type. However, an object declared with the static storage-class specifier can have a VM type (that is, a pointer to a VLA type). Finally, all identifiers declared with a VM type have to be ordinary identifiers and cannot, therefore, be members ostructures or unions.

This means that static storage and automatic storage are mutually exclusive.

John Kugelman
  • 349,597
  • 67
  • 533
  • 578
  • Hi, Remyabel, thanks for your reply. In this case, the compiler may generate the codes which will modify the stack pointer with a variable rather than a fixed number, is my guess correct? – user3769509 Oct 18 '14 at 21:02
  • I agree the phrase "dynamic array allocation on the stack" is very poor wording, but it is run-time, but it uses the syntax we're used to which used to be compile time declaration. Updating the answer to say that runtime array allocation ( with the length specified runtime ) is allowed is better than saying dynamic array allocation is not allowed. – Brian Bulkowski Aug 21 '19 at 17:28
3

For some delving into how allocating a variable amount of memory on the stack can work, see this delving into how a compiler can implement the (non-standardized) alloca() function:

Alloca implementation

The C99 standard offers Variable Length Arrays ("VLA") with essentially the same functionality; although the memory is reclaimed on a per-scope basis rather than a per-function basis:

What's the difference between alloca(n) and char x[n]?

There are some reasons to be hesitant to use either too aggressively with unbounded size. There's no way to check if stack memory is available as you can test for whether heap memory is available via. NULL from malloc(). If your variable length array is too large it will cause a stack overflow and undefined behavior; true for both methods of stack allocation:

Why is the use of alloca() not considered good practice?

Community
  • 1
  • 1
0

C has such a feature as Variable Length Arrays. Arrays with automatic storage duration can be defined in the flight.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335