@@ -897,20 +897,32 @@ fn (mut g Gen) struct_init_field(sfield ast.StructInitField, language ast.Langua
897897 && g.cur_struct_init_typ != 0 {
898898 struct_sym := g.table.sym (g.cur_struct_init_typ)
899899 if struct_sym.info is ast.Struct {
900- for f in struct_sym.info.fields {
901- if f.name == sfield.name {
902- // Only cast named function type aliases (e.g. ThreadCB),
903- // not anonymous function types from generic structs which
904- // may generate non-existent type names.
905- fsym := g.table.sym (f.typ)
906- if ! fsym.name.starts_with ('fn ' ) {
907- field_styp := g.styp (f.typ)
908- expr_styp := g.styp (sfield.typ)
909- if field_styp != expr_styp {
910- g.write ('(${field_styp} )' )
900+ if struct_sym.info.is_typedef {
901+ // For @[typedef] C structs, the actual C field types may differ
902+ // from V's declarations (e.g. C has `const char*` but V uses `char*`).
903+ // Use __typeof__ to cast to the actual C struct field type.
904+ c_struct_name := if struct_sym.cname.starts_with ('C__' ) {
905+ struct_sym.cname[3 ..]
906+ } else {
907+ struct_sym.cname
908+ }
909+ g.write ('(__typeof__(((${c_struct_name} ){}).${sfield.name} ))' )
910+ } else {
911+ for f in struct_sym.info.fields {
912+ if f.name == sfield.name {
913+ // Only cast named function type aliases (e.g. ThreadCB),
914+ // not anonymous function types from generic structs which
915+ // may generate non-existent type names.
916+ fsym := g.table.sym (f.typ)
917+ if ! fsym.name.starts_with ('fn ' ) {
918+ field_styp := g.styp (f.typ)
919+ expr_styp := g.styp (sfield.typ)
920+ if field_styp != expr_styp {
921+ g.write ('(${field_styp} )' )
922+ }
911923 }
924+ break
912925 }
913- break
914926 }
915927 }
916928 }
0 commit comments