One issue with D's design is that it uses
char a[..]
as syntax for a pointer, not an array. C has the same confusing issues in prototypes where it allows char[] notation for pointers, but this as it is widely seen as a mistake.
I do not agree that C VLAs are a terribly clumsy design. Especially from the point of dependent typing, C's design is the right one, e.g. you can express something such as
void transpose(int X, int Y, double (out)[X][Y], const double (in)[Y][X]);
If you only have existential types and not the fully dependent form, then this is not possible.
the pointer stars got lost, sorry.