Skip to content

Go silently drops the value of a constant (non-static) field, and of every instance-field initializer: the struct is zero-valued #111

Description

@matt-edmondson

What's wrong

GoGenerator decides where a field goes from IsStatic alone:

  • Coder/Languages/GoGenerator.cs ~line 580 writes package-level storage for field.IsStatic.
  • ~line 732 makes a struct member of !field.IsStatic.

A FieldDeclaration with IsConstant = true and IsStatic = false therefore becomes an ordinary struct field, and its InitialValue is dropped with no note. Every other target treats a constant as belonging to the type:

Target Output for Ratio (constant, 0.5)
C# public static readonly double Ratio = 0.5d;
C++ static constexpr double Ratio = 0.5;
Rust (fixed in #81) pub const Ratio: f64 = 0.5; via IsStatic || IsConstant
C double Ratio; // constant, 0.5
Go Ratio float64 (value lost)

Go also drops ordinary instance-field initializers without a note. Hits = 5 becomes Hits int, and the generated constructor returns Cfg{}. C at least writes // defaults to 5.

Repro

var cls = new ClassDeclaration("Cfg") { Kind = TypeDeclarationKind.Struct };
cls.Members.Add(new FieldDeclaration("Ratio", new TypeReference("double")) { IsConstant = true, InitialValue = Literal.DecimalValue(0.5) });
cls.Members.Add(new FieldDeclaration("Hits", new TypeReference("int")) { InitialValue = Literal.Number(5) });
cls.Members.Add(new FunctionDeclaration("Cfg") { Kind = FunctionKind.Constructor });
Console.WriteLine(new GoGenerator().Generate(cls));

Actual:

type Cfg struct {
	Ratio float64
	Hits  int
}
func NewCfg() Cfg { return Cfg{} }

Under go run, printing NewCfg()'s fields gives 0 0. The C# and C++ outputs give 0.5 and 5.

Suggested fix

  • Change both predicates to field.IsStatic || field.IsConstant, matching RustGenerator.IsAssociatedField. Ratio then becomes a package-level const CfgRatio float64 = 0.5, the same path static fields already take.
  • For instance fields with an InitialValue, set them in the generated constructor's composite literal (Cfg{Hits: 5}), or at least emit a note as the C generator does.

Acceptance criteria

  • Constant fields keep their value in Go output.
  • A struct with initialized instance fields constructed via NewX() reports the initial values, or the output carries an explicit note that they are not applied.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingreadyFully specified; implement as written

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions