Hello,<br><br>This is Part 1 of the language spec documentation review which I'm doing. So far I've covered maybe 1/3rd of the links in the spec docs.<br><br>I am going to make a bug report for this, but I was thinking it might be a good idea if someone could review my findings first (Let me know if you want the bug report right away and I will do one asap.). Some of these could likely be my own mistakes, or my misinterpretation of the docs.<br>
<br>The first column is the link to the docs section, the next indentation is the relevant subsection title (you'll have to do a CTRL+F to find the code examples, there's not that many 'href' anchors in the html docs, sorry), and the next indent are the errors/comments. When I say "example" in the text, I mean the relevant code example from the docs.<br>
<br>All of these examples were tested with DMD 2.046 on XP-32bit, unfortunately I had trouble setting up DSSS in Ubuntu (and I'm too lazy to make makefiles) so I didn't test on that platform.<br><br>So, here's the copypasta:<br>
<br><a href="http://www.digitalmars.com/d/2.0/module.html">http://www.digitalmars.com/d/2.0/module.html</a><br> "Mixin Declaration"<br> This should be moved to the "Declarations" section.<br>
<br> <br><a href="http://www.digitalmars.com/d/2.0/declaration.html">http://www.digitalmars.com/d/2.0/declaration.html</a><br> "Aliases cannot be used for expressions"<br> The code example compiles even though it says it is illegal.<br>
<br><br><a href="http://www.digitalmars.com/d/2.0/type.html">http://www.digitalmars.com/d/2.0/type.html</a><br> "Implicit Conversions"<br> Last line in the example:<br> f = E;<br> E is undefined, the line should be:<br>
f = Foo.E;<br> <br> "Delegates"<br> In the example, assigning the address of a function to a<br> function pointer gives a compilation error:<br> Error: cannot implicitly convert expression <br>
(&func) of type int delegate(int) to int function(int)<br><br> <br><a href="http://www.digitalmars.com/d/2.0/property.html">http://www.digitalmars.com/d/2.0/property.html</a><br> ".init Property"<br>
"Foo.b.init" is 0, not 7.<br><br> ".stringof Property"<br> Example contains two lines refering to "test.Foo",<br> but "test" isn't declared anywhere. <br>
The compiler output is different too.<br> <br> The lines should be replaced with:<br> writefln((1+2).stringof); // "1 + 2"<br> writefln(Foo.stringof); // "Foo"<br>
writefln(int.stringof); // "int"<br> writefln((int*[5][]).stringof); // "int*[5u][]"<br> writefln(Enum.RED.stringof); // "Enum<br> writefln((5).stringof); // "5"<br>
<br> ".sizeof Property"<br> Compilation error:<br> sizeof_test.d(14): Error: 'this' is only defined in non-static<br> member functions, not test<br> <br> Maybe a compiler bug? If "int x = S.a.sizeof" is put outside the<br>
test() function, it will compile.<br><br><br><a href="http://www.digitalmars.com/d/2.0/attribute.html">http://www.digitalmars.com/d/2.0/attribute.html</a><br> "immutable Attribute"<br> "__gshared Attribute"<br>
"shared Attribute"<br> "inout Attribute"<br> <br> There is missing documentation for these.<br><br> <br><a href="http://www.digitalmars.com/d/2.0/expression.html">http://www.digitalmars.com/d/2.0/expression.html</a> <br>
"A CatExpression concatenates arrays, producing a dynmaic"<br> typo: dynmaic > dynamic.<br> <br> "Array Literals"<br> Third example from the title:<br> writeln(ct); // writes [1 1]<br>
writeln(rt); // writes [257]<br> <br> The output is instead:<br> 1 1<br> 1 0 1 0<br> <br> "is ( Type Identifier )"<br> Replace any 'writefln' with 'writeln' (missing format specifiers).<br>
<br> "is ( Type Identifier : TypeSpecialization )"<br> Replace any 'writefln' with 'writeln'.<br><br> "is ( Type Identifier == TypeSpecialization , TemplateParameterList )"<br>
Replace any 'writefln' with 'writeln'.<br><br><a href="http://www.digitalmars.com/d/2.0/statement.html">http://www.digitalmars.com/d/2.0/statement.html</a><br> "Labeled Statements"<br>
It states:<br> ''Labels are in a name space independent of declarations, variables,<br> types, etc. Even so, labels *cannot* have the same name as local<br> declarations.''<br>
<br> However this custom example compiles:<br><br> void func() {<br> int t;<br> t: {<br> int xyz;<br> }<br> }<br><br> So does this one:<br> <br>
void func() {<br> int t;<br> xyz: {<br> int xyz;<br> }<br> }<br> <br> Perhaps this was meant to state:<br> "Declarations *inside* labels cannot have the same name<br>
as local declarations" ?<br> <br> "foreach_reverse"<br> IIRC this will be replaced with retro sometime soon? foreach_reverse<br> still works though.<br><br> "Foreach over Arrays of Characters"<br>
First example, these lines:<br> char[] a = "\xE2\x89\xA0"; // \u2260 encoded as 3 UTF-8 bytes<br> dchar[] b = "\u2260"; // prints 'a[] = 2260'<br> <br>
Should be replaced with:<br> char[] a = "\xE2\x89\xA0".dup; // \u2260 encoded as 3 UTF-8 bytes<br> dchar[] b = "\u2260"d.dup; // prints 'a[] = 2260'<br>
<br> "Foreach over Associative Arrays"<br> The first example code gives these compiler errors:<br> foreach_test.d(38): Error: function<br> object.AssociativeArray!(const(char)[],double).AssociativeArray.opApply<br>
(scope int delegate(ref const(char)[], ref double) dg) is not callable<br> using argument types (int delegate(ref double __applyArg0, <br> ref char[] __applyArg1))<br><br> foreach_test.d(38): Error: cannot implicitly convert expression<br>
(__foreachbody524) of type int delegate(ref double __applyArg0, <br> ref char[] __applyArg1) to int delegate(ref double)<br><br> Changing the foreach statement like so seems to work:<br> double[char[]] a;<br>
<br> foreach (const (char)[] s, ref double d; a)<br> {<br> writefln("a['%s'] = %g", s, d);<br> } <br> <br> "Foreach over Structs and Classes with opApply"<br>
The sentence:<br> <br> "The body of the apply function iterates over the elements it aggregates"<br> Has a typo, change "it aggregates" to "in aggregates".<br> <br>
"Foreach over Tuples"<br> In the first example, replace any 'writefln' with 'writeln'.<br> <br> In foreach over arrays it states:<br> ''The index must be of int, uint or size_t type''<br>
<br> In foreach over tuples it states:<br> ''The index must be of int or uint type.''<br> <br> Is there a reason why one is allowed to be of size_t type,<br> and the other is not?<br>
<br> "Foreach Restrictions"<br> The example:<br> int[] a;<br> int[] b;<br> foreach (int i; a)<br> {<br> a = null; // error<br>
a.length = a.length + 10; // error<br> a = b; // error<br> }<br> a = null; // ok<br><br> None of these give compilation errors or warnings.<br>
Adding memmory allocation statements for a and b before<br> entering the loop does not cause any compiler errors, and<br> no runtime exceptions are raised.<br> <br> "Switch Statement"<br>
The sentence:<br> ''If none of the case expressions match, and there is not a default<br> statement, a [link:std.switcherr.SwitchError] is thrown.''<br> <br> The link redirects to a 404 page. <br>
"std.switcherr.SwitchError" should be replaced <br> with "core.exception.SwitchError".<br><br> "Final Switch Statement"<br> What is this used for? CTFE maybe? I'm curious. :)<br>
<br> "Scope Guard Statement"<br> In all of the examples under this section<br> 'writefln' should be replaced with 'writeln',<br> and 'writef' with 'write'.<br>
<br> "Mixin Statement"<br> Replace 'writefln' with 'writeln' in the mixin string.<br> <br> The line:<br> char[] t = "y = 3;";<br> Replace it with:<br>
char[] t = "y = 3;".dup;<br> <br> Now only the documentation-relevant errors are shown when compiling.<br> <br> "Foreach Range Statement"<br> This should be moved up, close to where the other foreach definitions are.<br>
<br> In the example code:<br> Replace 'writefln' with 'writeln', and 'writef' with 'write'.<br><br><br><a href="http://www.digitalmars.com/d/2.0/arrays.html">http://www.digitalmars.com/d/2.0/arrays.html</a><br>
"Usage"<br> The lines:<br> p = s; // p points to the first element of the array s.<br> p = a; // p points to the first element of the array a.<br> <br> Give compiler errors:<br>
Error: cannot implicitly convert expression (s) of<br> type int[3u] to int*<br> Error: cannot implicitly convert expression (a) of<br> type int[] to int*<br> <br> Casts work:<br>
p = cast(int*) s;<br> p = cast(int*) a;<br> <br> But is that a good workaround? Don't ask me.. :p<br> <br> "Array Properties"<br> In the first example there are missing declarations. <br>
Could add these before the first line:<br> int* p;<br> int[3] s;<br> int[] a;<br><br> "Setting Dynamic Array Length"<br> From the comments in the first example, it states:<br>
''// always resized in place because it is sliced<br> // from a[] which has enough memory for 15 chars''<br> <br> But in this shorter example:<br> char[] a = new char[50];<br>
char[] b = a[0..10]; <br><br> b.length = 11; <br> a[3] = 'z'; <br> writeln(b); // writes 11 default characters<br><br> from my tests, resizing b to any bigger length always creates a copy, <br>
regardless of how big the length of a is.<br> <br> Resizing to a smaller length (e.g. 8) will keep the reference,<br> and b[3] will still refer to a[3] in the example.<br> <br> Has the resizing behavior changed recently, or is that comment inaccurate?<br>
<br> "Functions as Array Properties"<br> From this example code:<br> int[] array;<br> void foo(int[] a, int x);<br><br> foo(array, 3);<br> array.foo(3); // means the same thing<br>
<br> The last line does not compile, even when foo() is fully defined:<br> Error: undefined identifier module main.foo<br><br> "Array Bounds Checking"<br> In the example code, "ArrayBoundsError" should be replaced <br>
with "RangeError".<br> <br> "Static Initialization of Static Arrays"<br> For the example code:<br> enum Color { red, blue, green };<br> int value[Color.max + 1] = [ Color.blue:6, Color.green:2, Color.red:5 ];<br>
<br> The documentation states:<br> ''These arrays are static when they appear in global scope. <br> Otherwise, they need to be marked with const or static <br> storage classes to make them static arrays.''<br>
<br> In non-global scope, the array has to be marked with static in order<br> to compile. const alone is not compilable. At least not in my case.<br><br> "Special Array Types"<br> The 6th example from the title:<br>
cast(wchar [])"abc" // this is an array of wchar characters<br> "abc"w // so is this<br> <br> It should probably be noted that the first line returns a copy of the <br>
string with type wchar[], while the second line returns a copy(?) <br> of the string with type immutable(wchar)[]. But correct me if I'm wrong with this one.<br><br> The next example has this line:<br>
w = \r[0]; // w is assigned the carriage return wchar character<br> Needs to be replaced with:<br> w = "\r"[0]; // w is assigned the carriage return wchar character<br><br>
"Associative Arrays"<br> Accessing a nonexistent key for an AA throws the RangeError exception.<br> Perhaps a different exception should be created for AA's, such as:<br> core.exception.KeyNotInAssocArray<br>
?<br> <br> "Using Classes as the KeyType"<br> In the example code, any "f" in a declaration/expression needs to be<br> replaced with "foo".<br><br> "Using Structs or Unions as the KeyType"<br>
The line in the example:<br> foreach (char c; s)<br> Should be:<br> foreach (char c; str)<br><br>// end<br><br>