2

I know you're not supposed to declare arrays with a variable as the size ex. int arr[n]; because the size of an array is supposed to be static if not using dynamic memory but what about if you have a function like this? Would this be valid or no? It seems to run just fine.. Does the fact that it is declared inside a function have anything to do with it?

int main() {
  int n;
  scanf("%d", &n);
  exampleFunc(n);

}

void exampleFunc(int const n) {
  int arr[n];
  for (int i = 0; i < num; i++) {
    arr[i] = i + 1;
  }
}

Thanks for your help in advance. I'm a noob with C and every resource I've found is for other languages.

Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
g3or3
  • 63
  • 4
  • 5
    You are using *Variable-Length Array* and it is valid in C99. – MikeCAT Feb 05 '21 at 15:03
  • 5
    This is called a variable length array and was introduced in C99. But with later versions of C standard it was marked as optional. – Gerhardh Feb 05 '21 at 15:04

3 Answers3

1

From the GNU GCC documentation,

Variable-length automatic arrays are allowed in ISO C99.

If you're using the std=c99 flag, then it's guaranteed to be a valid code. But, keep in your mind that the variable-length array (VLAs) is not a standard part of C++ programming. It was a mandatory feature introduced in C99 standard.

This feature did become optional until the implementation has not defined __STDC_NO_VLA__ flag in C11 support. Thanks to @trentcl for this effective detail.

Rohan Bari
  • 7,482
  • 3
  • 14
  • 34
  • 1
    It's also valid C11, if the implementation does not define `__STDC_NO_VLA__`. VLAs were a mandatory feature in C99 that was rolled back to "optional" in C11. – trent Feb 05 '21 at 16:12
  • @trentcl thanks, I got to know just now. I've updated the answer. – Rohan Bari Feb 05 '21 at 16:33
1

For starters there is a typo in the for loop

for (int i = 0; i < num; i++) {

The variable num is undeclared. It seems you mean

for (int i = 0; i < n; i++) {

The function declaration shall be placed before its call.

There is no great sense to declare the parameter with the qualifier const.

void exampleFunc(int const n);

These two function declarations

void exampleFunc(int const n);

and

void exampleFunc(int n);

declare the same one function.

This declaration of an array within the function

int arr[n];

will be valid provided that your compiler supports variable length arrays. Otherwise the compiler will issue an error that the size of the array shall be an integer constant expression.

Variable length arrays shall have automatic storage duration. So even if your compiler supports variable length arrays you may not declare them outside any function like for example

const int n = 10;
int a[n];

int main( void )
{
    //...
}

Also you may not initialize variable length arrays in their declarations.

Here is a demonstrative program of using a variable length array.

#include <stdio.h>

void display_pattern( size_t n )
{
    for ( size_t i = 0; i < n; i++ )
    {
        int a[i+1];
        
        for ( size_t j = 0; j < i + 1; j++ ) a[j] = ( i + j ) % n;
        
        for ( size_t j = 0; j < i + 1; j++ ) printf( "%d ", a[j] );
        putchar( '\n' );
    }
}

int main(void) 
{
    display_pattern( 10 );
    
    return 0;
}

The program output is

0 
1 2 
2 3 4 
3 4 5 6 
4 5 6 7 8 
5 6 7 8 9 0 
6 7 8 9 0 1 2 
7 8 9 0 1 2 3 4 
8 9 0 1 2 3 4 5 6 
9 0 1 2 3 4 5 6 7 8 
Vlad from Moscow
  • 301,070
  • 26
  • 186
  • 335
0

The 1999 revision of the language introduced variable-length arrays, where the array dimension could be specified with a runtime variable rather than a compile-time constant1. They cover the exact use case in your exampleFunc, allowing you to declare a local array whose size isn't known until runtime without having to rely on malloc.

VLAs are limited in their use - they cannot be used as globals or be declared as static, you can't use an initializer in their declarations, and they cannot be arbitrarily large.

VLA support has been spotty among post-C99 implementations, and the 2011 revision made their support optional. To be completely safe, you should check against the language version and the __STDC_NO_VLA__ macro to determine whether your implementation supports them or not2:

void exampleFunc( const int n )
{
#if __STDC_VERSION__ >= 199901L && !defined(__STDC_NO_VLA__) 
  int arr[n];
#else
  int *arr = malloc( sizeof *arr * n );
#endif

// do stuff with arr

#if !(__STDC_VERSION__ >= 19901L && !defined(__STDC_NO_VLA__))
  free( arr );
#endif
}

  1. Despite the name, a variable-length array's size is fixed for any given definition; you can't resize it after it's been defined.
  2. Personally, I would reverse the sense of that feature macro, rename it __STDC_VLA__ and only define it if VLAs are supported, but I'm not on the standards committee.
John Bode
  • 119,563
  • 19
  • 122
  • 198