summaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2014-09-29 12:44:50 -0700
committerRobert Griesemer <gri@golang.org>2014-09-29 12:44:50 -0700
commitef2a8da42c986d3c1c078479f42d5a568a1c3647 (patch)
treee43172f3fcaae5d7b7492561b2abe8ee2f44309e /doc
parent2ecbfbd98ac610ea94d5173eabc3b36cb748fe52 (diff)
downloadgo-ef2a8da42c986d3c1c078479f42d5a568a1c3647.tar.gz
spec: specify variable initialization order explicitly
The existing spec rules on package initialization were contradictory: They specified that 1) dependent variables are initialized in dependency order, and 2) independent variables are initialized in declaration order. This 2nd rule cannot be satisfied in general. For instance, for var ( c = b + 2 a = 0 b = 1 ) because of its dependency on b, c must be initialized after b, leading to the partial order b, c. Because a is independent of b but is declared before b, we end up with the order: a, b, c. But a is also independent of c and is declared after c, so the order b, c, a should also be valid in contradiction to a, b, c. The new rules are given in form of an algorithm which outlines initialization order explicitly. gccgo and go/types already follow these rules. Fixes issue 8485. LGTM=iant, r, rsc R=r, rsc, iant, ken, gordon.klaus, adonovan CC=golang-codereviews https://codereview.appspot.com/142880043
Diffstat (limited to 'doc')
-rw-r--r--doc/go_spec.html53
1 files changed, 37 insertions, 16 deletions
diff --git a/doc/go_spec.html b/doc/go_spec.html
index 583517269..de79f7ee4 100644
--- a/doc/go_spec.html
+++ b/doc/go_spec.html
@@ -1,6 +1,6 @@
<!--{
"Title": "The Go Programming Language Specification",
- "Subtitle": "Version of September 25, 2014",
+ "Subtitle": "Version of September 29, 2014",
"Path": "/ref/spec"
}-->
@@ -5927,20 +5927,42 @@ var t T
</pre>
<h3 id="Package_initialization">Package initialization</h3>
+
+<p>
+Within a package, package-level variables are initialized in
+<i>declaration order</i> but after any of the variables
+they <i>depend</i> on.
+</p>
+
+<p>
+More precisely, a package-level variable is considered <i>ready for
+initialization</i> if it is not yet initialized and either has
+no <a href="#Variable_declarations">initialization expression</a> or
+its initialization expression has no dependencies on uninitialized variables.
+Initialization proceeds by repeatedly initializing the next package-level
+variable that is earliest in declaration order and ready for initialization,
+until there are no variables ready for initialization.
+</p>
+
<p>
-Within a package, package-level variables are initialized according
-to their <i>dependencies</i>: if a variable <code>x</code> depends on
-a variable <code>y</code>, <code>x</code> will be initialized after
-<code>y</code>.
+If any variables are still uninitialized when this
+process ends, those variables are part of one or more initialization cycles,
+and the program is not valid.
+</p>
+
+<p>
+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.
</p>
<p>
Dependency analysis does not rely on the actual values of the
variables, only on lexical <i>references</i> to them in the source,
-analyzed transitively. For instance, a variable <code>x</code>'s
-<a href="#Variable_declarations">initialization expression</a>
-may refer to a function whose body refers to variable <code>y</code>;
-if so, <code>x</code> depends on <code>y</code>.
+analyzed transitively. For instance, if a variable <code>x</code>'s
+initialization expression refers to a function whose body refers to
+variable <code>y</code> then <code>x</code> depends on <code>y</code>.
Specifically:
</p>
@@ -5973,11 +5995,6 @@ or to a function or method that depends on <code>y</code>.
Dependency analysis is performed per package; only references referring
to variables, functions, and methods declared in the current package
are considered.
-It is an error if variable dependencies form a cycle
-(but dependency cycles containing no variables are permitted).
-If two variables are independent of each other,
-they are initialized in the order they are declared
-in the source, possibly in multiple files, as presented to the compiler.
</p>
<p>
@@ -6000,8 +6017,6 @@ func f() int {
<p>
the initialization order is <code>d</code>, <code>b</code>, <code>c</code>, <code>a</code>.
-Since <code>b</code> and <code>c</code> are independent of each other, they are
-initialized in declaration order (<code>b</code> before <code>c</code>).
</p>
<p>
@@ -6044,6 +6059,12 @@ the <code>init</code> functions: it will not invoke the next one
until the previous one has returned.
</p>
+<p>
+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.
+</p>
+
<h3 id="Program_execution">Program execution</h3>
<p>