Да, это законно, если вы инициализируете объект с автоматическим сроком хранения (как в вашем примере).Для объектов со статической длительностью хранения , что было бы недопустимым, поскольку такие объекты допускают только константы выражений в своих инициализаторах.
Также имейте в виду, что в оценках Cвыражения инициализатора неопределенно упорядочены относительно друг друга.Это означает, что если у вас есть несколько вызовов функций среди ваших инициализаторов, и результаты этих функций зависят от некоторого общего состояния, эти инициализаторы могут вести себя непредсказуемо
int foo()
{
static int a;
return ++a;
}
int main()
{
struct { int x, y; } s = { foo(), foo() };
/* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
}
Что касается переносимости, можно заметить, что C89 / 90 сделалне разрешать этого (формально в C89 / 90 все {}
-замкнутые инициализаторы должны быть константными выражениями, даже для автоматических объектов), но большинство популярных компиляторов C89 / 90 поддерживали это независимо.