@@ -95,20 +95,6 @@ $(GNAME StorageClass):
9595 $(RELATIVE_LINK2 ref-storage, `ref`)
9696)
9797
98- $(H3 $(LNAME2 initializers, Initializers))
99-
100- $(GRAMMAR
101- $(GNAME Initializer):
102- $(GLINK VoidInitializer)
103- $(GLINK NonVoidInitializer)
104-
105- $(GNAME NonVoidInitializer):
106- $(GLINK2 expression, AssignExpression)$(LEGACY_LNAME2 ExpInitializer)
107- $(GLINK2 expression, ArrayLiteral)$(LEGACY_LNAME2 ArrayInitializer)
108- $(GLINK2 struct, StructInitializer)$(LEGACY_LNAME2 StructInitializer)
109- )
110-
111- $(P See also $(GLINK VoidInitializer).)
11298
11399$(H2 $(LNAME2 declaration_syntax, Declaration Syntax))
114100
@@ -197,7 +183,82 @@ int x, *y; // x is an int, y is a pointer to int
197183int x[], y; // x is an array/pointer, y is an int
198184)
199185
200- $(H2 $(LEGACY_LNAME2 AutoDeclaration, auto-declaration, Implicit Type Inference))
186+ $(H2 $(LEGACY_LNAME2 initializers, initialization, Initialization))
187+
188+ $(GRAMMAR
189+ $(GNAME Initializer):
190+ $(GLINK VoidInitializer)
191+ $(GLINK NonVoidInitializer)
192+
193+ $(GNAME NonVoidInitializer):
194+ $(GLINK2 expression, AssignExpression)$(LEGACY_LNAME2 ExpInitializer)
195+ $(GLINK2 expression, ArrayLiteral)$(LEGACY_LNAME2 ArrayInitializer)
196+ $(GLINK2 struct, StructInitializer)$(LEGACY_LNAME2 StructInitializer)
197+ )
198+
199+ $(P When no *Initializer* is given, a variable is set to the
200+ $(DDSUBLINK spec/property, init, default `.init` value) for
201+ its type.)
202+
203+ $(P A variable can be initialized with a $(I NonVoidInitializer).)
204+
205+ $(P See also: $(DDSUBLINK spec/arrays, array-initialization, Array Initialization).)
206+
207+ $(H3 $(LNAME2 void_init, Void Initialization))
208+
209+ $(GRAMMAR
210+ $(GNAME VoidInitializer):
211+ $(D void)
212+ )
213+
214+ $(P Normally a variable will be initialized.
215+ However, if a variable initializer is $(D void), the variable is *not* initialized.
216+ Void initializers for variables with a type that may contain
217+ $(DDSUBLINK spec/function, safe-values, unsafe values) (such as types with pointers)
218+ are not allowed in `@safe` code.
219+ )
220+
221+ $(IMPLEMENTATION_DEFINED If a void initialized variable's value is
222+ used before it is set, its value is implementation defined.
223+
224+ ---
225+ void bad()
226+ {
227+ int x = void;
228+ writeln(x); // print implementation defined value
229+ }
230+ ---
231+ )
232+
233+ $(UNDEFINED_BEHAVIOR If a void initialized variable's value is
234+ used before it is set, and the value is a reference, pointer or an instance
235+ of a struct with an invariant, the behavior is undefined.
236+
237+ ---
238+ void muchWorse()
239+ {
240+ char[] p = void;
241+ writeln(p); // may result in apocalypse
242+ }
243+ ---
244+ )
245+
246+ $(BEST_PRACTICE
247+ $(OL
248+ $(LI Void initializers are useful when a static array is on the stack,
249+ but may only be partially used, such as a temporary buffer.
250+ Void initializers will potentially speed up the code, but they introduce risk, since one must ensure
251+ that array elements are always set before read.)
252+ $(LI The same is true for structs.)
253+ $(LI Use of void initializers is rarely useful for individual local variables,
254+ as a modern optimizer will remove the dead store of its initialization if it is
255+ initialized later.)
256+ $(LI For hot code paths, it is worth profiling to see if the void initializer
257+ actually improves results.)
258+ )
259+ )
260+
261+ $(H3 $(LEGACY_LNAME2 AutoDeclaration, auto-declaration, Implicit Type Inference))
201262
202263$(GRAMMAR
203264$(GNAME AutoDeclaration):
@@ -241,6 +302,19 @@ auto c = new C(); // c is a handle to an instance of class C
241302 auto v = ["resistance", "is", "useless"]; // type is string[], not string[3]
242303 ---
243304
305+ $(H3 $(LNAME2 global_static_init, Global and Static Initializers))
306+
307+ $(P The $(GLINK Initializer) for a global or static variable must be
308+ evaluatable at compile time.
309+ Runtime initialization is done with $(DDSUBLINK spec/module, staticorder, static constructors).
310+ )
311+
312+ $(IMPLEMENTATION_DEFINED
313+ $(OL
314+ $(LI Whether some pointers can be initialized with the addresses of other
315+ functions or data.)
316+ ))
317+
244318
245319$(H2 $(LNAME2 alias, Alias Declarations))
246320
@@ -667,74 +741,6 @@ extern extern(C) int bar;
667741 connect with global variables declarations and functions in C or C++ files.)
668742 ))
669743
670- $(H2 $(LNAME2 void_init, Void Initializations))
671-
672- $(GRAMMAR
673- $(GNAME VoidInitializer):
674- $(D void)
675- )
676-
677- $(P Normally, variables are initialized either with an explicit
678- $(GLINK Initializer) or are set to the default value for the
679- type of the variable. If the $(I Initializer) is $(D void),
680- however, the variable is not initialized.
681- Void initializers for variables with a type that may contain
682- $(DDSUBLINK spec/function, safe-values, unsafe values) (such as types with pointers)
683- are not allowed in `@safe` code.
684- )
685-
686- $(IMPLEMENTATION_DEFINED If a void initialized variable's value is
687- used before it is set, its value is implementation defined.
688-
689- ---
690- void bad()
691- {
692- int x = void;
693- writeln(x); // print implementation defined value
694- }
695- ---
696- )
697-
698- $(UNDEFINED_BEHAVIOR If a void initialized variable's value is
699- used before it is set, and the value is a reference, pointer or an instance
700- of a struct with an invariant, the behavior is undefined.
701-
702- ---
703- void muchWorse()
704- {
705- char[] p = void;
706- writeln(p); // may result in apocalypse
707- }
708- ---
709- )
710-
711- $(BEST_PRACTICE
712- $(OL
713- $(LI Void initializers are useful when a static array is on the stack,
714- but may only be partially used, such as a temporary buffer.
715- Void initializers will potentially speed up the code, but they introduce risk, since one must ensure
716- that array elements are always set before read.)
717- $(LI The same is true for structs.)
718- $(LI Use of void initializers is rarely useful for individual local variables,
719- as a modern optimizer will remove the dead store of its initialization if it is
720- initialized later.)
721- $(LI For hot code paths, it is worth profiling to see if the void initializer
722- actually improves results.)
723- )
724- )
725-
726- $(H2 $(LNAME2 global_static_init, Global and Static Initializers))
727-
728- $(P The $(GLINK Initializer) for a global or static variable must be
729- evaluatable at compile time.
730- Runtime initialization is done with static constructors.
731- )
732-
733- $(IMPLEMENTATION_DEFINED
734- $(OL
735- $(LI Whether some pointers can be initialized with the addresses of other
736- functions or data.)
737- ))
738744
739745$(H2 $(LNAME2 typequal_vs_storageclass, Type Qualifiers vs. Storage Classes))
740746
0 commit comments