Using C99 I'm trying to do this within a function:
foo_t foos[4];
foos[0] = {1, {1,2}};
doesn't work. So I tried this...
foo_t foos[4];
foos[0] = (foo_t){1, {1,2}};
which works, but is it safe? Is there not perhaps a better way to do this?
The first case failed, because there no type associated with the expression (brace enclosed initializer)
Yes, the second code is safe, as long as the initializer list matches the expected types for the LHS. This is called compound literal, FWIW.
Quoting C11, chapter §6.5.2.5
A postfix expression that consists of a parenthesized type name followed by a brace enclosed list of initializers is a compound literal. It provides an unnamed object whose value is given by the initializer list.
foo_t foos[4] = {{1, {1,2}}};. Though that is not exactly equivalent to what you have shown as it zero intialises the elements at indices 1-3 whereas your example does not.