Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is the size of a variable length array computed at runtime in C99?

In C89, the length of an array is known at compile time. But in C99, with variable length arrays, the length of an array may be unknown before runtime.

So how does it get computed?

And why couldn't the length of a dynamically allocated array be computed in the same way?

like image 543
minh.hieu Avatar asked Dec 17 '12 04:12

minh.hieu


People also ask

How can you determine the size of an array at runtime?

In C++, we use sizeof() operator to find the size of desired data type, variables, and constants. It is a compile-time execution operator. We can find the size of an array using the sizeof() operator as shown: // Finds size of arr[] and stores in 'size' int size = sizeof(arr)/sizeof(arr[0]);

How is a variable length array defined?

In computer programming, a variable-length array (VLA), also called variable-sized or runtime-sized, is an array data structure whose length is determined at run time (instead of at compile time). In C, the VLA is said to have a variably modified type that depends on a value (see Dependent type).

Can we give size of array at run time?

Thus the size of the array is determined at the time of its creation or, initialization once it is done you cannot change the size of the array. Still if you try to assign value to the element of the array beyond its size a run time exception will be generated.

Can the size of an array be declared at runtime in C++?

Variable Length Arrays in C/C++ Variable length arrays are also known as runtime sized or variable sized arrays. The size of such arrays is defined at run-time.


1 Answers

From ISO/IEC 9899:TC3 Section 6.7.5.2: Array declarators

An ordinary identifier (as defined in 6.2.3) that has a variably modified type shall have either block scope and no linkage or function prototype scope. If an identifier is declared to be an object with static storage duration, it shall not have a variable length array type.

The sizeof a VLA is simply sizeof(vla_element_type) * vla_length. Since a VLA can only be defined within a block, its length must be either a local variable or a function parameter, which can be accessed by the compiler when the vla is accessed. (Since the length of vla and the vla itself belongs to the same stack frame).

Here is an example:

int main(int argc, char* argv[])
{
  int m;
  scanf("%d\n", &m);
  int a[m];

  printf("%d\n", sizeof(a));

  return 0;
}

Compiled with clang -o test.ll -O2 -emit-llvm -S test.c, the generated IR is shown as follows:

define i32 @main(i32 %argc, i8** nocapture %argv) nounwind {
entry:
  // Allocate space on stack for m
  %m = alloca i32, align 4  

  // call scanf
  %call = call i32 (i8*, ...)* @__isoc99_scanf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32* %m) nounwind  

  // %0 now contains the value of m
  %0 = load i32* %m, align 4, !tbaa !0

  // %1 is m << 2, which is m * sizeof(int)
  %1 = shl nuw i32 %0, 2  

  // call printf, output m * sizeof(int) to screen.
  %call1 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([4 x i8]* @.str, i32 0, i32 0), i32 %1) nounwind  

  // DONE.
  ret i32 0
}
like image 114
Lei Mou Avatar answered Oct 13 '22 18:10

Lei Mou