let rec reduce_initializer ~env ~typ init =
  match typ.ct_ty, init with
  | (Tarray ({ ct_ty = Tarray(_) } as et, _), CTTinitList(l)) ->
      let nl = List.map (reduce_initializer ~env ~typ:et) l in
      let nl = List.map (function CTTinitList(l) -> l | _ -> assert false) nl in
      CTTinitList(List.flatten nl)
  | (Tstruct id, CTTinitList(l)) ->
      CTTinitList(reduce_struct_initializations ~env id l)
  | (Tarray (t,_), CTTinitList(l)) -> 
      CTTinitList(List.map (reduce_initializer ~env ~typ:t) l)
  | (Tarray _ | Tpointer _ | Tbuiltin _), CTTinitExp(i) -> CTTinitExp(reduce_expr i)
  | (Tfunction _ | Tvoid), _ -> assert false
  | _ -> assert false

and reduce_struct_initializations ~env struct_id inits =
  let desc = get_struct_desc ~env struct_id in
  let rec iter fields inits = 
    match fields, inits with
      [], [] -> []
    | (_, NormalField { sf_type = t }) :: tl, ini::rest ->
        (reduce_initializer ~env ~typ:t ini) ::
        iter tl rest
    | (_, BitField { s_bf_fields = bf }) :: tl, inits ->
        iter_bfields tl bf inits
    | [], _::_ | _::_, [] -> assert false
  and iter_bfields rest_fields bfields inits = 
    match bfields, inits with
      [], rest_inits -> iter rest_fields inits 
    | (_,t,_,_)::tl, (init :: rest) ->
        (reduce_initializer ~env ~typ:t init)
        :: iter_bfields rest_fields tl rest
    | _::_, [] -> assert false
  in
  iter desc.str_fields inits