GCC에서는 char arr[a];로 할당받을 수 있습니다.
VC++ 등 일부 컴파일러는 가변 길이 배열(Variable Length Array, VLA)을 허용하지 않는데
컴파일러가 VLA를 허용하지 않는 경우에는 어쩔 수 없이 동적할당을 써야만 합니다.
C에서 편하게 동적으로 배열 크기를 지정하려면 VLA를 허용하는 GCC같은 컴파일러를 써야 합니다.
... 사실 동적 할당이라는 게 컴파일 시점에 크기가 정해지지 않은 할당을 말하는 건 아닙니다.
스택에 할당받아도 재귀호출이나 VLA로 컴파일 시점에 크기를 알 수 없는 경우도 있습니다.
스택에는 FIFO로, 순서대로 할당/해제하기 때문에 정적 할당이라고 하고, (빈 공간도 안 생깁니다.)
힙에는 아무때나 할당/해제하기 때문에 동적 할당이라고 합니다. (할당/해제 순서가 없습니다.)