Um, C compilers already do that with arrays with compile-time lengths.
#include <stdio.h>
void main(void) {
char x[20][30];
printf("%zu\n%zu\n", sizeof(x), sizeof(x[0]));
}
prints 600
30
so you can have "char *y = malloc(sizeof(x)); memcpy(y, x, sizeof(x));" and it must work since C89 at least. The main problem with VLAs is that they make exact the stack frame size unknown until runtime which complicates function prologues/epilogues but that's the problem in the codegen part of the backend, the semantics machinery is mostly in the place already.P.S. And yes, uecker is a member of the ISO C WG14 and GCC contributor, according to his profile.
Of course, this runtime tracking has always been necessary for C99 VLA support, but I can easily see how it would be surprising for someone not deeply familiar with VLAs, especially given how the naive mental model of "T array[n]; is just syntax sugar for T *array = alloca(n * sizeof(T));" is sufficient for almost all of their uses in existing code. (In any case, it's obviously not "creating an object on the heap" that's the unusual part here!)
Well, is it much more machinery? IIRC doing
void f(size_t n) {
int x[n];
n += 1;
...
does not resize x, so there is no dataflow dependency or rather, x depends on a hidden const variable so no additional dataflow analysis necessary. void f(size_t n, int cond) {
if (cond) { n += 1; }
int x[n];
...
does resize x depending on the value of cond, so the size can't necessarily be known until the point where the type (int[n] in this case) is named.Also, the compiler has to make sure it keeps around implicit locals to store the variable layouts, so that code like
void f(size_t n) {
typedef int array[n];
n += 1;
array x;
...
functions as specified. This kind of pattern is one of the bigger things setting the feature apart from just "syntax sugar for alloca()".