C99の可変長配列(VLA)はどれぐらい便利なのか

いわゆるANSI C(C90)では、配列のサイズは定数でなければなりません。つまり、配列を宣言する際には、

int a[10];

のように[]の中には定数を書く必要があり、

int a[size];

のように変数を書くことはできません(gccでは昔からできたりしましたが、それはgcc独自拡張です)。
しかし、C99からは、可変長配列(VLA: Variable Length Array)の機能が追加され、配列の要素数に変数(というか定数でない式)が書けるようになりました。
ただ、VLAが使えるのは自動変数(staticでないローカル変数)だけです。まあ静的配列の要素数が可変というのもいまいち意味が分からないので無理はありませんが、一時的にしか存在できない自動変数の配列のサイズが可変にできたところで、あまり便利じゃないのでは、とも思えます。まあ、実行時にしかサイズが決まらない一時的な作業バッファとかにはよいかもしれません。今時Cを使っている環境だと組み込み系とか多そうで、スタックのサイズ制限がきつかったりしてあまり気楽には使えない、ということもありそうです。
ただし、VLAの構文は、たとえばmalloc()で確保した領域にも使えます。
たとえばオセロでも囲碁でもマインスイーパーでもいいのですが、何らかのゲームの「盤面」を2次元配列で確保するとします。オセロの盤面は普通は8×8ですが、もっと広い盤面も選択できるようにしてもよいでしょう。そういう場合は、縦横が可変長の2次元配列が欲しくなります。しかし、ANSI Cでは、縦横可変の可変長配列を作ることはできません(ポインタを駆使して、board[x][y]の形式でアクセスできる可変サイズの領域を確保することはできなくはないですが)。
VLAであれば、たとえば盤面の1つのマスをint型で表現するとして、以下のように書くことで、size×sizeの2次元配列を確保できます。

int (*board)[size] = malloc(sizeof(int) * size * size);

もちろん、盤面の各マスは、board[x][y]のようにしてアクセス可能です。
これを関数の引数として受け渡しするときは、受け取る側の関数のプロトタイプは以下のように書けます。

void func(int size, int board[size][size]);

これは、

void func(int size, int (*board)[size]);

シンタックスシュガーです。私はこのシンタックスシュガーはあまり好みではないのですが、さすがにこのケースでは、前者の例の方が意図をよく表していてわかりやすいかなあ、と思います……
さて、宣伝しますよ。
VLAをはじめ、C99の機能についてもいろいろ解説した「C言語 ポインタ完全制覇」改訂版発売中ですよ!