@@ -95,20 +95,6 @@ $(GNAME StorageClass):
95
95
$(RELATIVE_LINK2 ref-storage, `ref`)
96
96
)
97
97
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).)
112
98
113
99
$(H2 $(LNAME2 declaration_syntax, Declaration Syntax))
114
100
@@ -197,7 +183,82 @@ int x, *y; // x is an int, y is a pointer to int
197
183
int x[], y; // x is an array/pointer, y is an int
198
184
)
199
185
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))
201
262
202
263
$(GRAMMAR
203
264
$(GNAME AutoDeclaration):
@@ -241,6 +302,19 @@ auto c = new C(); // c is a handle to an instance of class C
241
302
auto v = ["resistance", "is", "useless"]; // type is string[], not string[3]
242
303
---
243
304
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
+
244
318
245
319
$(H2 $(LNAME2 alias, Alias Declarations))
246
320
@@ -667,74 +741,6 @@ extern extern(C) int bar;
667
741
connect with global variables declarations and functions in C or C++ files.)
668
742
))
669
743
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
- ))
738
744
739
745
$(H2 $(LNAME2 typequal_vs_storageclass, Type Qualifiers vs. Storage Classes))
740
746
0 commit comments