Package variable dependency analysis

November 14, 2024

Today’s section of the spec is a bit dense and technical. But don’t worry, it makes a lot of sense once we get to the end.

Package initialization

Dependency analysis does not rely on the actual values of the variables, only on lexical references to them in the source, analyzed transitively. For instance, if a variable x’s initialization expression refers to a function whose body refers to variable y then x depends on y. Specifically:

  • A reference to a variable or function is an identifier denoting that variable or function.
  • A reference to a method m is a method value or method expression of the form t.m, where the (static) type of t is not an interface type, and the method m is in the method set of t. It is immaterial whether the resulting function value t.m is invoked.
  • A variable, function, or method x depends on a variable y if x’s initialization expression or body (for functions and methods) contains a reference to y or to a function or method that depends on y.

For example, given the declarations

var (
	a = c + b  // == 9
	b = f()    // == 4
	c = f()    // == 5
	d = 3      // == 5 after initialization has finished
)

func f() int {
	d++
	return d
}

the initialization order is d, b, c, a.

All of this to say that what would make intutive sense holds: If, for example, a package-level variable initialization calls a function, which in turn references a package-level variable,then the dependency on that underlying package variable follows through to the other package variable. Phewh. No wonder the above section is so verbose and technical. I can’t even say it a concise way, other than: Dependencies at this level work as one would expect.

One last point in this section:

… Note that the order of subexpressions in initialization expressions is irrelevant: a = c + b and a = b + c result in the same initialization order in this example.

That is to say that the initialization order is determined by the order in which the dependant variables are declared in the source, not on the order in which they’re referenced. Because b is mentioned one line before c, b gets initialized beofre c, regardless of the order in which they’re mentioned as subexpressions in the declaration of a.

Whewh.


Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


init functions

We’ve been looking at the order of package variable initialization. What if these rules are confusing? Or even non-desterministic for you? Or maybe you simply want to do something more advanced than is feasible in package variable declarations. Is there an alternative? There is! Package initialization … Variables may also be initialized using functions named init declared in the package block, with no arguments and no result parameters. func init() { … } Note that package variables can be initialized, but not declared within an init function.


When package variable initialization order isn't defined

We’re nearing the end of the discussion on package initialization order. Monday should be the last day on that topic, but more on that shortly. Up to now, we’ve been looking at the deterministic order-of-initialization rules.Today’s topic is when that order is not defined. Package initialization … Dependency analysis is performed per package; only references referring to variables, functions, and (non-interface) methods declared in the current package are considered. If other, hidden, data dependencies exists between variables, the initialization order between those variables is unspecified.


Variable declaration across files

Package initialization … The declaration order of variables declared in multiple files is determined by the order in which the files are presented to the compiler: Variables declared in the first file are declared before any of the variables declared in the second file, and so on. To ensure reproducible initialization behavior, build systems are encouraged to present multiple files belonging to the same package in lexical file name order to a compiler.

Get daily content like this in your inbox!

Subscribe