1

I have some questions regarding array declarations in C99 standard.

int n;

scanf("%d", &n);

int v[n];

Does this create an array that has different size? I know that it can be a constant or a constant variable. But I think it has to have a known value at compile time, and the size should not change.

But I saw the above mentioned syntax multiple times, and I do not know that is a defenitive bug.

The second question is in relation to arrays passed to functions.

void printing(int v[])

and

void printing(int *v)

Is there a difference between the two declarations?

Tandura
  • 866
  • 2
  • 7
  • 19
  • 3
    Related: [In which versions of the C standard are variable length arrays not part of the language, required, or optional?](https://stackoverflow.com/questions/55696680/in-which-versions-of-the-c-standard-are-variable-length-arrays-not-part-of-the-l). – jarmod Nov 06 '21 at 21:50
  • 2
    `int v[n];` is a variable length array. It is a c99 feature and became optional after that. Some compilers, notably Microsoft, do not support VLA as it is not fully c99 compliant. The VLA size is determined at runtime and can change each time it is defined (e.g. in a function). – kaylum Nov 06 '21 at 21:52

1 Answers1

3

C99 introduced support for Variably Modified (VM) types. These types consist of parameters that are not known until runtime. The line:

int v[n];

creates an automatic variable of array type, whose size is defined at runtime. Those objects are known as Variable Length Arrays (VLA).

This is a valid C99 syntax though it is considered a risky practice because the mechanism for allocation of any automatic objects does not provide any error detection. This is especially problematic for automatic VLAs whose size is not known at compilation time. Automatic objects are usually allocated on the stack, which is a scarce resource (typically a few MiB on hosted machines, kilobytes on embedded systems).

Moreover, Undefined Behavior occurs if n is non-positive.

On your second question., the following declarations:

void printing(T v[]);
void printing(T *v);

are typically equivalent because type of parameter of array type is automatically adjusted to a pointer type. For example int v[] and int v[10] are adjusted to int*. float A[10][10] is adjusted to float (*A)[10].

Though there are a few differences:

  • T can be incomplete when forming T *v, however it must be complete when using array type.
struct S; // incomplete type
void foo(struct S *s); // ok
void foo(struct S s[]); // error
  • it is possible tell the compiler the minimum number of elements for the array v by using the static keyword
void foo(int v[static 10]);

The compiler can assume that access to v[0]...v[9] is valid.

void foo(int v[static 1]);

Tells the compiler that v is not NULL.

tstanisl
  • 13,520
  • 2
  • 25
  • 40