@@ -301,7 +301,7 @@ $(GNAME AutoDeclarationY):
301
301
static x = 3; // x is type int
302
302
auto y = 4u; // y is type uint
303
303
304
- auto s = "string "; // s is type immutable(char)[]
304
+ auto s = "Apollo "; // s is type immutable(char)[]
305
305
306
306
class C { ... }
307
307
@@ -318,11 +318,9 @@ auto c = new C(); // c is a handle to an instance of class C
318
318
is inferred to be a dynamic array
319
319
type rather than a static array:)
320
320
321
- ---
322
- auto v = ["hello", "world"]; // type is string[], not string[2]
323
- ---
324
-
325
-
321
+ ---
322
+ auto v = ["resistance", "is", "useless"]; // type is string[], not string[3]
323
+ ---
326
324
327
325
328
326
$(H2 $(LNAME2 alias, Alias Declarations))
@@ -367,13 +365,13 @@ void foo(myint m) { ... } // error, multiply defined function foo
367
365
For example:
368
366
)
369
367
370
- ----------------- ---
371
- import string ;
368
+ ---
369
+ import planets ;
372
370
373
- alias mylen = string.strlen ;
374
- ...
375
- int len = mylen("hello "); // actually calls string.strlen ()
376
- ----------------- ---
371
+ alias myAlbedo = planets.albedo ;
372
+ ...
373
+ int len = myAlbedo("Saturn "); // actually calls planets.albedo ()
374
+ ---
377
375
378
376
$(P
379
377
The following alias declarations are valid:
@@ -410,7 +408,7 @@ version (linux)
410
408
--------------------
411
409
412
410
$(P
413
- Aliasing can be used to $(SINGLEQUOTE import) a symbol from an import into the
411
+ Aliasing can be used to ` import` a symbol from an import into the
414
412
current scope:
415
413
)
416
414
@@ -419,7 +417,7 @@ alias strlen = string.strlen;
419
417
--------------------
420
418
421
419
$(P
422
- Aliases can also $(SINGLEQUOTE import) a set of overloaded functions, that can
420
+ Aliases can also ` import` a set of overloaded functions, that can
423
421
be overloaded with functions in the current scope:
424
422
)
425
423
@@ -482,8 +480,7 @@ $(H2 $(LNAME2 extern, Extern Declarations))
482
480
483
481
$(P Variable declarations with the storage class $(D extern) are not allocated
484
482
storage within the module. They must be defined in some other object file with a
485
- matching name which is then linked in. The primary usefulness of this is to
486
- connect with global variable declarations in C files.)
483
+ matching name which is then linked in.)
487
484
488
485
$(P An $(D extern) declaration can optionally be followed by an $(D extern)
489
486
$(LINK2 attribute.html$(HASH)linkage, linkage attribute). If there is no linkage
@@ -497,6 +494,12 @@ extern(C) int foo;
497
494
extern extern(C) int bar;
498
495
---------------
499
496
497
+ $(BEST_PRACTICE
498
+ $(OL
499
+ $(LI The primary usefulness of $(I Extern Declarations) is to
500
+ connect with global variables declarations and functions in C or C++ files.)
501
+ ))
502
+
500
503
$(H2 $(LNAME2 typeof, $(D typeof)))
501
504
502
505
$(GRAMMAR
@@ -537,7 +540,7 @@ $(GNAME Typeof):
537
540
}
538
541
--------------------
539
542
540
- $(P There are three special cases: )
543
+ $(P Special cases: )
541
544
$(OL
542
545
$(LI $(D typeof(this)) will generate the type of what $(D this)
543
546
would be in a non-static member function, even if not in a member
@@ -582,9 +585,11 @@ $(GNAME Typeof):
582
585
typeof(S.foo) n; // n is declared to be an int
583
586
--------------------
584
587
585
- $(P
586
- Where $(I Typeof) is most useful is in writing generic
587
- template code.
588
+ $(BEST_PRACTICE
589
+ $(OL
590
+ $(LI $(I Typeof) is most useful in writing generic
591
+ template code.)
592
+ )
588
593
)
589
594
590
595
$(H2 $(LNAME2 void_init, Void Initializations))
@@ -595,36 +600,55 @@ $(GNAME VoidInitializer):
595
600
)
596
601
597
602
$(P Normally, variables are initialized either with an explicit
598
- $(I Initializer) or are set to the default value for the
603
+ $(GLINK Initializer) or are set to the default value for the
599
604
type of the variable. If the $(I Initializer) is $(D void),
600
605
however, the variable is not initialized. If its value is
601
606
used before it is set, undefined program behavior will result.
602
607
)
603
608
604
- -------------------------
605
- void foo()
606
- {
607
- int x = void;
608
- writeln(x); // will print garbage
609
- }
610
- -------------------------
609
+ $(UNDEFINED_BEHAVIOR If a void initialized variable's value is
610
+ used before it is set, the behavior is undefined.
611
+
612
+ ---
613
+ void foo()
614
+ {
615
+ int x = void;
616
+ writeln(x); // will print garbage
617
+ }
618
+ ---
619
+ )
611
620
612
- $(P Therefore, one should only use $(D void) initializers as a
613
- last resort when optimizing critical code.
621
+ $(BEST_PRACTICE
622
+ $(OL
623
+ $(LI Void initializers are useful when a static array is on the stack,
624
+ but may only be partially used, such as as a temporary buffer.
625
+ Void initializers will speed up the code, but of course one must be careful
626
+ that array elements are actually set before read.)
627
+ $(LI The same is true for structs.)
628
+ $(LI Use of void initializers is rarely useful for individual local variables,
629
+ as a modern optimizer will remove the dead store of its initialization if it is
630
+ initialized later.)
631
+ $(LI For hot code paths, it is worthwhile to check to see if the void initializer
632
+ actually improves results before using it.)
633
+ )
614
634
)
615
635
616
636
$(H2 $(LNAME2 global_static_init, Global and Static Initializers))
617
637
618
638
$(P The $(GLINK Initializer) for a global or static variable must be
619
639
evaluatable at compile time.
620
- Whether some pointers can be initialized with the addresses of other
621
- functions or data is implementation defined.
622
- Runtime initialization can be done with static constructors.
640
+ Runtime initialization is done with static constructors.
623
641
)
624
642
643
+ $(IMPLEMENTATION_DEFINED
644
+ $(OL
645
+ $(LI Whether some pointers can be initialized with the addresses of other
646
+ functions or data.)
647
+ ))
648
+
625
649
$(H2 $(LNAME2 typequal_vs_storageclass, Type Qualifiers vs. Storage Classes))
626
650
627
- $(P D draws a distinction between a type qualifer and a storage class .)
651
+ $(P Type qualifer and storage classes are distinct .)
628
652
629
653
$(P A $(I type qualifier) creates a derived type from an existing base
630
654
type, and the resulting type may be used to create multiple instances
@@ -644,7 +668,7 @@ ImmutableInt z; // typeof(z) == immutable(int)
644
668
--------
645
669
646
670
$(P A $(I storage class), on the other hand, does not create a new
647
- type, but describes only the type of storage used by the variable or
671
+ type, but describes only the kind of storage used by the variable or
648
672
function being declared. For example, a member function can be declared
649
673
with the $(D const) storage class to indicate that it does not modify
650
674
its implicit $(D this) argument:)
@@ -663,7 +687,7 @@ struct S
663
687
664
688
$(P Although some keywords can be used both as a type qualifier and a
665
689
storage class, there are some storage classes that cannot be used to
666
- construct new types. One example is $(D ref):)
690
+ construct new types, such as $(D ref):)
667
691
668
692
--------
669
693
// ref declares the parameter x to be passed by reference
@@ -683,9 +707,9 @@ void main()
683
707
}
684
708
--------
685
709
710
+ $(P Functions can also be declared as `ref`, meaning their return value is
711
+ passed by reference:)
686
712
--------
687
- // Functions can also be declared as 'ref', meaning their return value is
688
- // passed by reference:
689
713
ref int func2()
690
714
{
691
715
static int y = 0;
@@ -710,36 +734,50 @@ void main()
710
734
}
711
735
--------
712
736
713
- $(P Due to the fact that some keywords, such as $(D const), can be used
714
- both as a type qualifier and a storage class, it may sometimes result
715
- in ambiguous-looking code: )
737
+ $(P Some keywords, such as $(D const), can be used
738
+ both as a type qualifier and a storage class.
739
+ The distinction is determined by the syntax where it appears. )
716
740
717
- --------
718
- struct S
719
- {
720
- // Is const here a type qualifier or a storage class?
721
- // Is the return value const(int), or is this a const function that returns
722
- // (mutable) int?
723
- const int func() { return 1; }
724
- }
725
- --------
741
+ ---
742
+ struct S
743
+ {
744
+ /* Is const here a type qualifier or a storage class?
745
+ * Is the return value const(int), or is this a const function that returns
746
+ * (mutable) int?
747
+ */
748
+ const int* func() // a const function
749
+ {
750
+ ++p; // error, this.p is const
751
+ return p; // error, cannot convert const(int)* to int*
752
+ }
753
+
754
+ const(int)* func() // a function returning a pointer to a const int
755
+ {
756
+ ++p; // ok, this.p is mutable
757
+ return p; // ok, int* can be implicitly converted to const(int)*
758
+ }
759
+
760
+ int* p;
761
+ }
762
+ ---
726
763
727
- $(P To avoid such confusion, it is recommended that type qualifier
728
- syntax with parentheses always be used for return types, and that
729
- function storage classes be written on the right-hand side of the
764
+ $(BEST_PRACTICE To avoid confusion, the type qualifier
765
+ syntax with parentheses should be used for return types,
766
+ and function storage classes should be written on the right-hand side of the
730
767
declaration instead of the left-hand side where it may be visually
731
- confused with the return type:)
768
+ confused with the return type:
732
769
733
- ----- ---
734
- struct S
735
- {
736
- // Now it is clear that the 'const' here applies to the return type:
737
- const(int) func1() { return 1; }
770
+ ---
771
+ struct S
772
+ {
773
+ // Now it is clear that the 'const' here applies to the return type:
774
+ const(int) func1() { return 1; }
738
775
739
- // And it is clear that the 'const' here applies to the function:
740
- int func2() const { return 1; }
741
- }
742
- --------
776
+ // And it is clear that the 'const' here applies to the function:
777
+ int func2() const { return 1; }
778
+ }
779
+ ---
780
+ )
743
781
744
782
$(SPEC_SUBNAV_PREV_NEXT module, Modules, type, Types)
745
783
)
0 commit comments