Skip to content

clang: allow array values in struct literals - #109

Closed
bbodi wants to merge 1 commit into
solod-dev:mainfrom
bbodi:fix/struct-lit-array-value
Closed

bbodi wants to merge 1 commit into
solod-dev:mainfrom
bbodi:fix/struct-lit-array-value

Conversation

@bbodi

@bbodi bbodi commented Oct 17, 2026

Copy link
Copy Markdown

What

A struct literal can now set an array field from an array value:

arr := [3]int{1, 2, 3}
b := Box{nums: arr} // was a compile error

Why

C brace initializers cannot copy an array. The generator therefore rejected any array field value that was not an array literal. Users had to declare the struct first and then assign the field.

How

The generator emits such a literal as a GNU statement expression. The expression fills a temporary with the other fields and copies each array with memcpy:

({ box _lit1 = {}; memcpy(_lit1.nums, arr, sizeof(so_int[3])); _lit1; })

The temporary initializer uses designators for every field, because the copied array fields are left out of it.

Limits

Three cases still require an array literal, and each case keeps the existing error:

  • A package-level initializer, because C does not allow a statement expression at file scope.
  • An anonymous struct literal, because the temporary needs a type name.
  • An array literal element.

Taking the address of such a literal (&Box{nums: arr}) is a new error. A statement expression produces a value with no address.

Testing

  • testdata/arrays covers keyed and positional fields, two array fields in one literal, array parameters, a call result as the value, a slice literal element, and a method call on the literal.
  • New testdata/bad cases cover the package-level, anonymous struct, and address-of errors.
  • go test ./... passes.

doc/spec.md describes the new rule and its limits.

A struct literal could only set an array field from an array literal.
C brace initializers cannot copy an array, so Box{nums: arr} failed
to compile. Users had to declare the struct and assign the field.

The generator now emits such a literal as a statement expression. The
expression fills a temporary and copies each array with memcpy.

Three cases still require an array literal: a package-level
initializer, an anonymous struct literal, and an array literal
element. Taking the address of such a literal is an error, because a
statement expression has no address.
@nalgeon

nalgeon commented Oct 17, 2026

Copy link
Copy Markdown
Collaborator

Sorry, I'm against making the compiler more complicated in regards to array, slice, and struct handling — it's already complex enough. You can just use b.nums = arr.

@nalgeon nalgeon closed this Oct 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants