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

浪尽此生 提交于 2019-11-28 00:10:34

问题


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?


回答1:


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
}



回答2:


The difference between a VLA and a malloced array that you hold through a pointer variable (besides living in different parts of the memory) is that the compiler knows at compile time that the first is an array. It can hold the size information(s) in some place along with the VLA, so basically this is some sort of hidden variable(s). Depending on the usage that you do with that variable, if e.g you use sizeof with it or if you index a 2D VLA through something like A[i][j] the compiler can then decide if that hidden variable is really needed, and, if not, optimize it out.



来源:https://stackoverflow.com/questions/13908421/how-is-the-size-of-a-variable-length-array-computed-at-runtime-in-c99

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!