Skip to content

Commit 51235d8

Browse files
authored
Merge pull request #2114 from WalterBright/declaration-touchup
declaration.dd: some minor touchups and improvements merged-on-behalf-of: MetaLang <MetaLang@users.noreply.github.com>
2 parents 5ebdef1 + 91585be commit 51235d8

File tree

1 file changed

+101
-63
lines changed

1 file changed

+101
-63
lines changed

spec/declaration.dd

Lines changed: 101 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,7 @@ $(GNAME AutoDeclarationY):
301301
static x = 3; // x is type int
302302
auto y = 4u; // y is type uint
303303

304-
auto s = "string"; // s is type immutable(char)[]
304+
auto s = "Apollo"; // s is type immutable(char)[]
305305

306306
class C { ... }
307307

@@ -318,11 +318,9 @@ auto c = new C(); // c is a handle to an instance of class C
318318
is inferred to be a dynamic array
319319
type rather than a static array:)
320320

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+
---
326324

327325

328326
$(H2 $(LNAME2 alias, Alias Declarations))
@@ -367,13 +365,13 @@ void foo(myint m) { ... } // error, multiply defined function foo
367365
For example:
368366
)
369367

370-
--------------------
371-
import string;
368+
---
369+
import planets;
372370

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+
---
377375

378376
$(P
379377
The following alias declarations are valid:
@@ -410,7 +408,7 @@ version (linux)
410408
--------------------
411409

412410
$(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
414412
current scope:
415413
)
416414

@@ -419,7 +417,7 @@ alias strlen = string.strlen;
419417
--------------------
420418

421419
$(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
423421
be overloaded with functions in the current scope:
424422
)
425423

@@ -482,8 +480,7 @@ $(H2 $(LNAME2 extern, Extern Declarations))
482480

483481
$(P Variable declarations with the storage class $(D extern) are not allocated
484482
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.)
487484

488485
$(P An $(D extern) declaration can optionally be followed by an $(D extern)
489486
$(LINK2 attribute.html$(HASH)linkage, linkage attribute). If there is no linkage
@@ -497,6 +494,12 @@ extern(C) int foo;
497494
extern extern(C) int bar;
498495
---------------
499496

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+
500503
$(H2 $(LNAME2 typeof, $(D typeof)))
501504

502505
$(GRAMMAR
@@ -537,7 +540,7 @@ $(GNAME Typeof):
537540
}
538541
--------------------
539542

540-
$(P There are three special cases: )
543+
$(P Special cases: )
541544
$(OL
542545
$(LI $(D typeof(this)) will generate the type of what $(D this)
543546
would be in a non-static member function, even if not in a member
@@ -582,9 +585,11 @@ $(GNAME Typeof):
582585
typeof(S.foo) n; // n is declared to be an int
583586
--------------------
584587

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+
)
588593
)
589594

590595
$(H2 $(LNAME2 void_init, Void Initializations))
@@ -595,36 +600,55 @@ $(GNAME VoidInitializer):
595600
)
596601

597602
$(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
599604
type of the variable. If the $(I Initializer) is $(D void),
600605
however, the variable is not initialized. If its value is
601606
used before it is set, undefined program behavior will result.
602607
)
603608

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+
)
611620

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+
)
614634
)
615635

616636
$(H2 $(LNAME2 global_static_init, Global and Static Initializers))
617637

618638
$(P The $(GLINK Initializer) for a global or static variable must be
619639
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.
623641
)
624642

643+
$(IMPLEMENTATION_DEFINED
644+
$(OL
645+
$(LI Whether some pointers can be initialized with the addresses of other
646+
functions or data.)
647+
))
648+
625649
$(H2 $(LNAME2 typequal_vs_storageclass, Type Qualifiers vs. Storage Classes))
626650

627-
$(P D draws a distinction between a type qualifer and a storage class.)
651+
$(P Type qualifer and storage classes are distinct.)
628652

629653
$(P A $(I type qualifier) creates a derived type from an existing base
630654
type, and the resulting type may be used to create multiple instances
@@ -644,7 +668,7 @@ ImmutableInt z; // typeof(z) == immutable(int)
644668
--------
645669

646670
$(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
648672
function being declared. For example, a member function can be declared
649673
with the $(D const) storage class to indicate that it does not modify
650674
its implicit $(D this) argument:)
@@ -663,7 +687,7 @@ struct S
663687

664688
$(P Although some keywords can be used both as a type qualifier and a
665689
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):)
667691

668692
--------
669693
// ref declares the parameter x to be passed by reference
@@ -683,9 +707,9 @@ void main()
683707
}
684708
--------
685709

710+
$(P Functions can also be declared as `ref`, meaning their return value is
711+
passed by reference:)
686712
--------
687-
// Functions can also be declared as 'ref', meaning their return value is
688-
// passed by reference:
689713
ref int func2()
690714
{
691715
static int y = 0;
@@ -710,36 +734,50 @@ void main()
710734
}
711735
--------
712736

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.)
716740

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+
---
726763

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
730767
declaration instead of the left-hand side where it may be visually
731-
confused with the return type:)
768+
confused with the return type:
732769

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; }
738775

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+
)
743781

744782
$(SPEC_SUBNAV_PREV_NEXT module, Modules, type, Types)
745783
)

0 commit comments

Comments
 (0)