I don't envy how much tech debt they have to deal with, while still trying to make it possible for new code to have a more modern experience. For all the excitement around new languages, we're still going to have a lot of C code for a long time, and difficult work like this should be appreciated.
>> So what is the current status? How many packages are going to be affected by this change? How are we going to track the progress?
> I see an unaudited rebuild failure rate of about 10% for rebuilds of source packages that produce arch-full binary packages. This number does not include packages which fail to build in rawhide without the compiler change. It includes packages which configure checks for something that we really do not support (like setproctitle or strlcpy). After the first pass completes, I'll have to do a second pass with the expected-to-be-undeclared functions gathered from the first pass filtered out. That should give us better numbers.
Sanity is such a rare thing these days.
This is how stable it is - they were still supporting C constructs from prior to C89 standardisation (which is when, I believe, void pointers were introduced).
"maybe consider using void * in more places (particularly for old programs that predate the introduction of void * into the C language). "
I'm curious how these dynamics play out in less popular compilers. If a compiler implemented VLAs in C99, they almost certainly still have that feature for backwards compatibility even after they support C11.
Is there any compiler which appeared on the scene between C11 and C23, and during that window, chose not to support VLAs and thus C99? It's not like C11 itself was very widely adopted, precisely because of the long implementation and industry rollout windows.
For these reasons, we propose to make variably-modified types
mandatory in C23. VLAs with automatic storage duration remain an optional language
feature due to their higher implementation overhead and security concerns on some
implementations (i.e. when allocated on the stack and not using stack probing).
from N2778 (https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2778.pdf)> Variable length arrays with automatic storage duration are a conditional feature that implementations need not support
confused
void function(int n) {
int (*arr)[n] = malloc(sizeof(*arr));
}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()".https://en.wikipedia.org/wiki/Variable-length_array#C99
If that phrasing isn't accurate I'm sure they'd appreciate an edit.
void example(int n) { printf("%zu", sizeof(int[n])); }
void example2(int n, int (*a)[n]) { }
This is optional: void example3(int n) { int x[n]; }