diff -uNr dmd-0.149/dmd/html/d/abi.html dmd-0.150/dmd/html/d/abi.html --- dmd-0.149/dmd/html/d/abi.html 2006-03-03 08:22:14.000000000 +0100 +++ dmd-0.150/dmd/html/d/abi.html 2006-03-18 10:52:50.000000000 +0100 @@ -25,7 +25,7 @@ | Comments -
- - In general, (a[n..m] op e) is defined as: - -
for (i = n; i < m; i++)
- a[i] op e;
-
-
- So, for the expression:
-
-a[] = b[] + 3; -- - the result is equivalent to: - -
for (i = 0; i < a.length; i++)
- a[i] = b[i] + 3;
-
When more than one [] operator appears in an expression, the range
represented by all must match.
diff -uNr dmd-0.149/dmd/html/d/attribute.html dmd-0.150/dmd/html/d/attribute.html
--- dmd-0.149/dmd/html/d/attribute.html 2006-03-03 08:22:12.000000000 +0100
+++ dmd-0.150/dmd/html/d/attribute.html 2006-03-18 10:52:50.000000000 +0100
@@ -25,7 +25,7 @@
| Comments
- + +
diff -uNr dmd-0.149/dmd/html/d/dlinks.html dmd-0.150/dmd/html/d/dlinks.html --- dmd-0.149/dmd/html/d/dlinks.html 2006-03-07 13:59:44.000000000 +0100 +++ dmd-0.150/dmd/html/d/dlinks.html 2006-03-18 10:52:50.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -
MatchExpression: - EqualExpression ~~ RelExpression - -NotMatchExpression: - EqualExpression !~ RelExpression -- -
Match expressions test to see if there's a match for a string - against a regular expression. Both operands must be implicitly - convertible to char[]. The left operand is the regular - expression, in the same form as supported by the - std.regexp module. - The right operand is the string to match against it. -
- -MatchExpression gives a !=null result of type object._Match* - when there is a match, - null when there is not a match. - NotMatchExpression gives a boolean - result of true when there is no match, and false - when there is a match. -
- -If the left operand does not form a valid regular expression, - a runtime - std.regexp.RegExpException - is thrown. - If invalid regular expressions can be detected at compile time, the - compiler may diagnose it as illegal. -
- -assert("bc" ~~ "abcd"); // succeeds -assert("^bc" ~~ "abcd"); // fails -if ("[a..d]*" !~ "abcd") - assert(0); // this line is not executed -assert("ab" ~~ 5); // error, 5 is not a char[] -assert("*" ~~ "5"); // "*" is not a valid regular expression; - // std.regexp.RegExpExpression is thrown - // at runtime -- -
When a MatchExpression is the operand of - an IfStatement or WhileStatement, special handling - happens. -
-RelExpression < ShiftExpression @@ -913,15 +857,32 @@diff -uNr dmd-0.149/dmd/html/d/faq.html dmd-0.150/dmd/html/d/faq.html --- dmd-0.149/dmd/html/d/faq.html 2006-03-03 08:22:14.000000000 +0100 +++ dmd-0.150/dmd/html/d/faq.html 2006-03-18 10:52:52.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Delete Expressions
- Delete expressions delete memory on the garbage collected - heap, or using a class or struct specific deallocator. - The UnaryExpression must be a reference to a class - object, a pointer to a struct object, a pointer, or - a dynamic array. + If the UnaryExpression is a class object reference, and + there is a destructor for that class, the destructor + is called for that object instance. ++ + Next, if the UnaryExpression is a class object reference, or + a pointer to a struct instance, and the class or struct + has overloaded operator delete, then that operator delete is called + for that class object instance or struct instance. +
+ + Otherwise, the garbage collector is called to immediately free the + memory allocated for the class instance or struct instance. + If the garbage collector was not used to allocate the memory for + the instance, undefined behavior will result. +
+ + If the UnaryExpression is a pointer or a dynamic array, + the garbage collector is called to immediately release the + memory. + If the garbage collector was not used to allocate the memory for + the instance, undefined behavior will result.
- The pointer or reference is set to null after the delete - is performed. + The pointer, dynamic array, or reference is set to null + after the delete is performed.
Cast Expressions
@@ -1475,10 +1436,10 @@ { static if ( is(bar T == int) ) // not satisfied, short is not int alias T S; - alias T U; // error, T is not defined + alias T U; // error, T is not defined static if ( is(E V == enum) ) // satisified, E is an enum - V x; // x is declared to be a byte + V x; // x is declared to be a byte }
Walter's SDWest 2006 + +presentation on D templates.
+Walter's SDWest 2004 presentation on D.
diff -uNr dmd-0.149/dmd/html/d/interface.html dmd-0.150/dmd/html/d/interface.html --- dmd-0.149/dmd/html/d/interface.html 2006-03-03 08:22:14.000000000 +0100 +++ dmd-0.150/dmd/html/d/interface.html 2006-03-18 10:52:50.000000000 +0100 @@ -25,7 +25,7 @@ | Comments -Walter's SDWest 2006 + +presentation on D templates.
+Walter's SDWest 2004 presentation on D.
diff -uNr dmd-0.149/dmd/html/d/lex.html dmd-0.150/dmd/html/d/lex.html --- dmd-0.149/dmd/html/d/lex.html 2006-03-03 08:22:12.000000000 +0100 +++ dmd-0.150/dmd/html/d/lex.html 2006-03-18 10:52:50.000000000 +0100 @@ -25,7 +25,7 @@ | Comments -bit[] foo; --
/* Sieve of Eratosthenes prime numbers */ -bit[8191] flags; +bool[8191] flags; int main() { int i, count, prime, k, iter; diff -uNr dmd-0.149/dmd/html/d/phobos/object.html dmd-0.150/dmd/html/d/phobos/object.html --- dmd-0.149/dmd/html/d/phobos/object.html 2006-03-07 14:37:00.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/object.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:36:59 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:28 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_base64.html dmd-0.150/dmd/html/d/phobos/std_base64.html --- dmd-0.149/dmd/html/d/phobos/std_base64.html 2006-03-07 14:37:00.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_base64.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:36:58 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:28 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_bitarray.html dmd-0.150/dmd/html/d/phobos/std_bitarray.html --- dmd-0.149/dmd/html/d/phobos/std_bitarray.html 2006-03-07 14:37:02.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_bitarray.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:37:00 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:29 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_c_fenv.html dmd-0.150/dmd/html/d/phobos/std_c_fenv.html --- dmd-0.149/dmd/html/d/phobos/std_c_fenv.html 1970-01-01 01:00:00.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_c_fenv.html 2006-03-18 23:51:30.000000000 +0100 @@ -0,0 +1,223 @@ + + + + + + + +Digital Mars - The D Programming Language - std.c.fenv + + + + + + +
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.fenv+ + +C's <fenv.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + +
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.math+ + +C's <math.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + +
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.process+ + +C's <process.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + + |
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.stdarg+ + +C's <stdarg.h> ++Authors: +Hauke Duden and Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + + |
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.stddef+ + +C's <stddef.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + + |
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.stdio+ + +C's <stdio.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + +
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.stdlib+ + +C's <stdlib.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + +
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.string+ + +C's <string.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + +
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.time+ + +C's <time.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + + |
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.c.wcharh+ + +C's <wchar.h> ++Authors: +Walter Bright, Digital Mars, www.digitalmars.com + +License: +Public Domain + + + |
// This code is derived from the // RSA Data Security, Inc. MD5 Message-Digest Algorithm. -import std.md5; -import std.string; -import std.c.stdio; -import std.stdio; +module std.md5; + +private import std.stdio; +private import std.string; +private import std.c.stdio; +private import std.c.string; int main(char[][] args) { diff -uNr dmd-0.149/dmd/html/d/phobos/std_outbuffer.html dmd-0.150/dmd/html/d/phobos/std_outbuffer.html --- dmd-0.149/dmd/html/d/phobos/std_outbuffer.html 2006-03-07 14:37:00.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_outbuffer.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:36:58 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:28 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_path.html dmd-0.150/dmd/html/d/phobos/std_path.html --- dmd-0.149/dmd/html/d/phobos/std_path.html 2006-03-07 14:36:58.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_path.html 2006-03-18 23:51:28.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:36:57 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:27 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_random.html dmd-0.150/dmd/html/d/phobos/std_random.html --- dmd-0.149/dmd/html/d/phobos/std_random.html 2006-03-07 14:37:00.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_random.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:36:59 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:28 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
diff -uNr dmd-0.149/dmd/html/d/phobos/std_regexp.html dmd-0.150/dmd/html/d/phobos/std_regexp.html --- dmd-0.149/dmd/html/d/phobos/std_regexp.html 2006-03-07 14:37:02.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_regexp.html 2006-03-18 23:51:30.000000000 +0100 @@ -24,7 +24,7 @@ | D | Comments -Last update Tue Mar 7 14:37:00 2006 +@@ -84,15 +84,22 @@ std.utfLast update Sat Mar 18 23:51:29 2006
std.zip
std.zlib
+ std.c.fenv
+ std.c.math
+ std.c.process
+ std.c.stdarg
+ std.c.stddef
+ std.c.stdio
+ std.c.stdlib
+ std.c.string
+ std.c.time
+ std.c.wcharh
std.windows.charset
std.windows
std.linux
-std.c
- std.c.stdio
-
std.c.windows
std.c.linux
@@ -105,14 +112,14 @@std.regexp
-Regular expressions +Regular expressions are a powerful method of string pattern matching. The regular expression language used is the same as that commonly used, however, some of the very advanced forms may behave slightly differently.
In the following guide, pattern[] refers to a - regular expression. + regular expression. The attributes[] refers to a string controlling the interpretation of the regular expression. diff -uNr dmd-0.149/dmd/html/d/phobos/std_stdint.html dmd-0.150/dmd/html/d/phobos/std_stdint.html --- dmd-0.149/dmd/html/d/phobos/std_stdint.html 2006-03-01 09:34:32.000000000 +0100 +++ dmd-0.150/dmd/html/d/phobos/std_stdint.html 2006-03-18 23:51:30.000000000 +0100 @@ -1,265 +1,270 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - -Digital Mars - The D Programming Language - std.stdint - - - - - - -
- - -object - - -std - std.base64 - std.bitarray - std.boxer - std.compiler - std.conv - std.ctype - std.date - std.demangle - std.file - std.format - std.gc - std.intrinsic - std.math - std.md5 - std.mmfile - std.openrj - std.outbuffer - std.path - std.process - std.random - std.recls - std.regexp - std.socket - std.socketstream - std.stdint - std.stdio - std.cstream - std.stream - std.string - std.system - std.thread - std.uni - std.uri - std.utf - std.zip - std.zlib - -std.windows - -std.linux - -std.c - std.c.stdio - -std.c.windows - -std.c.linux - - - |
-
-
-
-std.stdint- - - - D constrains integral types to specific sizes. But efficiency - of different sizes varies from machine to machine, - pointer sizes vary, and the maximum integer size varies. - stdint offers a portable way of trading off size - vs efficiency, in a manner compatible with the stdint.h - definitions in C. -- - The exact aliases are types of exactly the specified number of bits. - The at least aliases are at least the specified number of bits - large, and can be larger. - The fast aliases are the fastest integral type supported by the - processor that is at least as wide as the specified number of bits. - - - The aliases are: - - -
- - The ptr aliases are integral types guaranteed to be large enough - to hold a pointer without losing bits: - - -
- - The max aliases are the largest integral types: - - -
|
+ + +object + + +std + std.base64 + std.boxer + std.compiler + std.conv + std.cover + std.ctype + std.date + std.demangle + std.file + std.format + std.gc + std.intrinsic + std.math + std.md5 + std.mmfile + std.openrj + std.outbuffer + std.path + std.process + std.random + std.recls + std.regexp + std.socket + std.socketstream + std.stdint + std.stdio + std.cstream + std.stream + std.string + std.system + std.thread + std.uri + std.utf + std.zip + std.zlib + std.c.fenv + std.c.math + std.c.process + std.c.stdarg + std.c.stddef + std.c.stdio + std.c.stdlib + std.c.string + std.c.time + std.c.wcharh + std.windows.charset + +std.windows + +std.linux + +std.c.windows + +std.c.linux + + + |
+
+
+
+std.stdint+ + +D constrains integral types to specific sizes. But efficiency + of different sizes varies from machine to machine, + pointer sizes vary, and the maximum integer size varies. + stdint offers a portable way of trading off size + vs efficiency, in a manner compatible with the stdint.h + definitions in C. ++The exact aliases are types of exactly the specified number of bits. + The at least aliases are at least the specified number of bits + large, and can be larger. + The fast aliases are the fastest integral type supported by the + processor that is at least as wide as the specified number of bits. + + + The aliases are: + + +
+ + The ptr aliases are integral types guaranteed to be large enough + to hold a pointer without losing bits: + + +
+ + The max aliases are the largest integral types: + + +
+Authors: +Walter Bright, www.digitalmars.com + +License: +Public Domain + + + |
+
+
+
+
+ + + · Overview + + + · D for Win32 + + + · Win32 DLLs in D + + + · C .h to D Modules + + + · FAQ + + + · Style Guide + + + · Example: wc + + + · Future + + + · D Change Log + + + · Tech Tips + + + · Rationale + + + · Exception Safety + + + · Templates Revisited + + + · Warnings + + + · Glossary + + + · Acknowledgements + + + + Tools + + · DMD D Compiler + + + · GDC D Compiler + + + · Linker + + + · Profiler + + + · Code Coverage + + + · DMD Script Shell + + + + Community + + + · News + + + · Forum + + + · Announcements + + + · Learn + + + · D links + + + + Archives + + · digitalmars.D + + + · digitalmars.D.dtl + + + · digitalmars.D.announce + + + · digitalmars.D.dwt + + + · digitalmars.D.learn + + + · digitalmars.D.bugs + + + · D.gnu + + + · Old D + + + + + |
+
+
+Templates Revisited+ ++ + + +"What I am going to tell you about is what we teach our programming students in +the third or fourth year of graduate school... It is my task to convince you not +to turn away because you don't understand it. You see my programming students +don't understand it... That is because I don't understand it. Nobody does."+ Abstract+ +Templates in C++ have evolved from little more than token substitution into a +programming language in itself. Many useful aspects of C++ templates have been +discovered rather than designed. A side effect of this is that C++ templates are +often criticized for having an awkward syntax, many arcane rules, and being very +difficult to implement properly. What might templates look like if one takes a +step back, looks at what templates can do and what uses they are put to, and +redesign them? Can templates be powerful, aesthetically pleasing, easy to +explain and straightforward to implement? +This article takes a look at an alternative design of templates in the D +Programming Language [1]. + + +Similarities+ +
Argument Syntax+ +The first thing that comes to mind is the use of < > to enclose parameter +lists and argument lists. < > has a couple serious problem, however. +They are ambiguous with operators <, >, and >>. This means that expressions +like: + + +a<b,c>d; ++ +and: + + a<b<c>>d; ++ + are syntactically ambiguous, both to the compiler and the programmer. +If you run across a<b,c>d; in unfamiliar code, you've got to slog through +an arbitrarilly large amount of declarations and .h files to figure out +if it is a template or not. +How much effort has been expended by programmers, compiler writers, and +language standard writers to deal with this? + + +There's got to be a better way. D solves it by noticing that ! is not used +as a binary operator, so replacing: + + +a<b,c> ++ + with: + + +a!(b,c) ++ + is syntactically unambiguous. This makes it easy to parse, easy to generate +reasonable error messages for, and makes it easy for someone inspecting the +code to determine that yes, a must be a template. + + + +Template Definition Syntax+ +C++ can define two broad types of templates: class templates, and function +templates. Each template is written independently, even if they are +closely related: + + +template<T, U> class Bar { ... }; + +template<T, U> T foo(T t, U u) { ... } + +template<T, U> static T abc; ++ + POD (Plain Old Data, as in C style) structs +bring together related data declarations, classes bring together +related data and function declarations, but there's nothing to logically group +together templates that are to be instantiated together. +In D, we can write: + + +template Foo(T, U) +{ +class Bar { ... } + +T foo(T t, U u) { ... } + +T abc; + +typedef T* Footype; // any declarations can be templated +} ++ + The Foo forms a name space for the templates, which are accessed by, +for example: + + +Foo!(int,char).Bar b; +Foo!(int,char).foo(1,2); +Foo!(int,char).abc = 3; ++ + Of course, this can get a little tedious, so one can use an alias +for a particular instantiation: + + +alias Foo!(int,char) f; +f.Bar b; +f.foo(1,2); +f.abc = 3; ++ + For class templates, there's an even simpler syntax. A class is defined +like: + + +class Abc +{ + int t; + ... +} ++ + This can be turned into a template by just adding a parameter list: + + +class Abc(T)
+{
+ T t;
+ ...
+}
+
+
+
+Template Declaration, Definition, and Export+ +C++ templates can be in the form of a template declaration, a template +definition, and an exported template. +Because D has a true module system, rather than textual #include files, +there are only template definitions in D. The need for template declarations +and export is irrelevant. For example, given a template definition in +module A: + + +module A; + +template Foo(T) +{ + T bar; +} ++ + it can be accessed from module B like: + + +module B; + +import A; + +void test() +{ + A.Foo!(int).bar = 3; +} ++ + As usual, an alias can be used to simplify access: + + +module B; + +import A; +alias A.Foo!(int).bar bar; + +void test() +{ + bar = 3; +} ++ + + Template Parameters+ +C++ template parameters can be: + +
D template parameters can be: + +
Each can have default values, +and type parameters can have (a limited form of) constraints: + + +class B { ... } +interface I { ... } + +class Foo( + R, // R can be any type + P:P*, // P must be a pointer type + T:int, // T must be int type + S:T*, // S must be pointer to T + C:B, // C must be of class B or derived + // from B + U:I, // U must be a class that + // implements interface I + char[] string = "hello", + // string literal, + // default is "hello" + alias A = B // A is any symbol + // (including template symbols), + // defaulting to B + ) +{ + ... +} ++ + Specialization+ +Partial and explicit specialization work as they do in C++, except that +there is no notion of a 'primary' template. All the templates with the +same name are examined upon template instantiation, and the one with the +best fit of arguments to parameters is instantiated. + + +template Foo(T) ... +template Foo(T:T*) ... +template Foo(T, T) ... +template Foo(T, U) ... +template Foo(T, U:int) ... + +Foo!(long) // picks Foo(T) +Foo!(long[]) // picks Foo(T), T is long[] +Foo!(int*) // picks Foo(T*), T is int +Foo!(long,long) // picks Foo(T, T) +Foo!(long,short) // picks Foo(T, U) +Foo!(long,int) // picks Foo(T, U:int) +Foo!(int,int) // ambiguous - Foo(T, T) + // or Foo(T, U:int) ++ + Two Level Name Lookup+ +C++ has some unusual rules for name lookup inside templates, such +as not looking inside base classes, not allowing scoped redeclaration +of template parameter names, and not considering overloads that +happen after the point of definition (this example is +derived from one in the C++98 Standard): + + +int g(double d) { return 1; } + +typedef double A; + +template<class T> B +{ + typedef int A; +}; + +template<class T> struct X : B<T> +{ + A a; // a has type double + int T; // error, T redeclared + int foo() + { char T; // error, T redeclared + return g(1); // always returns 1 + } +}; + +int g(int i) { return 2; } // this definition not seen by X ++ + Scoped lookup rules in D match the rules for the rest of the language: + + +int g(double d) { return 1; } + +typedef double A; + +class B(T) +{ + typedef int A; +} + +class X(T) : B!(T) +{ + A a; // a has type int + int T; // ok, T redeclared as int + int foo() + { char T; // ok, T redeclared as char + return g(1); // always returns 2 + } +}; + +int g(int i) { return 2; } // functions can be forward referenced ++ + + + Template Recursion+ +Template recursion combined with specialization means that C++ templates +actually form a programming language, although certainly +an odd one. Consider a set of templates that computes a factorial at +run time. Like "hello world" programs, factorial is the canonical example +of template metaprogramming: + + +template<int n> class factorial +{ + public: + enum + { + result = n * factorial<n - 1>::result + }; +}; + +template<> class factorial<1> +{ + public: + enum { result = 1 }; +}; + +void test() +{ + // prints 24 + printf("%d\n", factorial<4>::result); +} ++ + Recursion works as well in D, though with significantly less typing: + + +template factorial(int n) +{ + const factorial = n * factorial!(n-1); +} + +template factorial(int n : 1) +{ + const factorial = 1; +} + +void test() +{ + writefln(factorial!(4)); // prints 24 +} ++ + Through using the static if construct it can be done in just one template: + + +template factorial(int n) +{ + static if (n == 1) + const factorial = 1; + else + const factorial = n * factorial!(n-1); +} ++ + reducing 13 lines of code to an arguably much cleaner 7 lines. +static if's are the equivalent of C++'s #if. +But #if cannot access template +arguments, so all template conditional compilation must be handled with +partial and explicitly specialized templates. +static if dramatically simplifies +such constructions. + + + +SFINAE - Substitution Failure Is Not An Error+ +This determines if the template's argument type is a function, +from "C++ Templates: The Complete Guide", +Vandevoorde & Josuttis pg. 353: + + +template<U> class IsFunctionT +{ + private: + typedef char One; + typedef struct { char a[2]; } Two; + template static One test(...); + template static Two test(U (*)[1]); + public: + enum { + Yes = sizeof(IsFunctionT::test(0)) == 1 + }; +}; + +void test() +{ + typedef int (fp)(int); + + assert(IsFunctionT<fp>::Yes == 1); +} ++ + Template IsFunctionT relies on two side effects to achieve its result. +First, it relies on arrays of functions being an invalid C++ type. +Thus, if U is a function type, the second test will not be selected +since to do so would cause an error (SFINAE). The first test will be selected. +If U is not a function type, the second test is a better fit than ... . +Next, it is determined which test was selected by examining the size +of the return value, i.e. sizeof(One) or sizeof(Two). +Unfortunately, template metaprogramming in C++ often seems to be relying +on side effects rather than being able to expressly code what is desired. + + +In D this can be written: + + +template IsFunctionT(T) +{ + static if ( is(T[]) ) + const int IsFunctionT = 1; + else + const int IsFunctionT = 0; +} + +void test() +{ + typedef int fp(int); + + assert(IsFunctionT!(fp) == 1); +} ++ + The is(T[]) is the equivalent of SFINAE. +It tries to build an array of T, +and if T is a function type, it is an array of functions. Since this is +an invalid type, the T[] fails and is(T[]) returns false. + + +Although SFINAE can be used, the is expressions can test a type directly, +so it isn't even necessary to use a template to ask questions about a type: + + +void test() +{ + typedef int fp(int); + + assert( is(fp == function) ); +} ++ + Template Metaprogramming With Floats+ +Let's move on to things that are impractical with templates in C++. +For example, this template returns the square root of +real number x using the Babylonian method: + + +import std.stdio; + +template sqrt(real x, real root = x/2, int ntries = 0) +{ + static if (ntries == 5) + // precision doubles with each iteration, + // 5 should be enough + const sqrt = root; + else static if (root * root - x == 0) + const sqrt = root; // exact match + else + // iterate again + const sqrt = sqrt!(x, (root+x/root)/2, ntries+1); +} + +void main() +{ + real x = sqrt!(2); + writefln("%.20g", x); // 1.4142135623730950487 +} ++ + Literal square roots are often needed for speed reasons in other runtime +floating point computations, such as computing the gamma function. +These template floating point algorithms need not be efficient as they are +computed at compile time, they only need to be accurate. + + +Much more complex templates can be built, for example, Don Clugston +has written a template to compute π at compile time. [2] + + +Template Metaprogramming With Strings+ +Even more interesting things can be done with strings. This example +converts an integer to a string at compile time: + + +template decimalDigit(int n) // [3] +{ + const char[] decimalDigit = "0123456789"[n..n+1]; +} + +template itoa(long n) +{ + static if (n < 0) + const char[] itoa = "-" ~ itoa!(-n); + else static if (n < 10) + const char[] itoa = decimalDigit!(n); + else + const char[] itoa = itoa!(n/10L) ~ decimalDigit!(n%10L); +} + +char[] foo() +{ + return itoa!(264); // returns "264" +} ++ + This template will compute the hash of a string literal: + + +template hash(char [] s, uint sofar=0) +{ + static if (s.length == 0) + const hash = sofar; + else + const hash = hash!(s[1 .. length], sofar * 11 + s[0]); +} + +uint foo() +{ + return hash!("hello world"); +} ++ + Regular Expression Compiler+ +How do D templates fare with something much more significant, like +a regular expression compiler? Eric Niebler has written one for C++ +that relies on expression templates. [4] +The problem with using expression templates is that one is restricted +to using only C++ operator syntax and precedence. +Hence, regular expressions using expression templates don't look like +regular expressions, they look like C++ expressions. +Eric Anderton has written one for D that relies on the ability of +templates to parse strings. [5] +This means that, within the strings, one can use the expected regular +expression grammar and operators. + + +The regex compiler templates parse the regex string argument, +pulling off tokens +one by one from the front, and instantiating custom template functions +for each token predicate, +eventually combining them all into one function that directly implements +the regular expression. +It even gives reasonable error messages for syntax errors in +the regular expression. + + +Calling that function with an argument of a string to match returns +an array of matching strings: + + +import std.stdio; +import regex; + +void main() +{ + auto exp = ®exMatch!(r"[a-z]*\s*\w*"); + writefln("matches: %s", exp("hello world")); +} ++ + What follows is a cut-down version of Eric Anderton's regex compiler. +It is just enough to compile the regular expression above, +serving to illustrate how it is done. + + +module regex; + +const int testFail = -1; + +/** + * Compile pattern[] and expand to a custom generated + * function that will take a string str[] and apply the + * regular expression to it, returning an array of matches. + */ + +template regexMatch(char[] pattern) +{ + char[][] regexMatch(char[] str) + { + char[][] results; + int n = regexCompile!(pattern).fn(str); + if (n != testFail && n > 0) + results ~= str[0..n]; + return results; + } +} + +/****************************** + * The testXxxx() functions are custom generated by templates + * to match each predicate of the regular expression. + * + * Params: + * char[] str the input string to match against + * + * Returns: + * testFail failed to have a match + * n >= 0 matched n characters + */ + +/// Always match +template testEmpty() +{ + int testEmpty(char[] str) { return 0; } +} + +/// Match if testFirst(str) and testSecond(str) match +template testUnion(alias testFirst, alias testSecond) +{ + int testUnion(char[] str) + { + int n1 = testFirst(str); + if (n1 != testFail) + { + int n2 = testSecond(str[n1 .. $]); + if (n2 != testFail) + return n1 + n2; + } + return testFail; + } +} + +/// Match if first part of str[] matches text[] +template testText(char[] text) +{ + int testText(char[] str) + { + if (str.length && + text.length <= str.length && + str[0..text.length] == text + ) + return text.length; + return testFail; + } +} + +/// Match if testPredicate(str) matches 0 or more times +template testZeroOrMore(alias testPredicate) +{ + int testZeroOrMore(char[] str) + { + if (str.length == 0) + return 0; + int n = testPredicate(str); + if (n != testFail) + { + int n2 = testZeroOrMore!(testPredicate)(str[n .. $]); + if (n2 != testFail) + return n + n2; + return n; + } + return 0; + } +} + +/// Match if term1[0] <= str[0] <= term2[0] +template testRange(char[] term1, char[] term2) +{ + int testRange(char[] str) + { + if (str.length && str[0] >= term1[0] + && str[0] <= term2[0]) + return 1; + return testFail; + } +} + +/// Match if ch[0]==str[0] +template testChar(char[] ch) +{ + int testChar(char[] str) + { + if (str.length && str[0] == ch[0]) + return 1; + return testFail; + } +} + +/// Match if str[0] is a word character +template testWordChar() +{ + int testWordChar(char[] str) + { + if (str.length && + ( + (str[0] >= 'a' && str[0] <= 'z') || + (str[0] >= 'A' && str[0] <= 'Z') || + (str[0] >= '0' && str[0] <= '9') || + str[0] == '_' + ) + ) + { + return 1; + } + return testFail; + } +} + +/*****************************************************/ + +/** + * Returns the front of pattern[] up until + * the end or a special character. + */ + +template parseTextToken(char[] pattern) +{ + static if (pattern.length > 0) + { + static if (isSpecial!(pattern)) + const char[] parseTextToken = ""; + else + const char[] parseTextToken = + pattern[0..1] ~ parseTextToken!(pattern[1..$]); + } + else + const char[] parseTextToken=""; +} + +/** + * Parses pattern[] up to and including terminator. + * Returns: + * token[] everything up to terminator. + * consumed number of characters in pattern[] parsed + */ +template parseUntil(char[] pattern,char terminator,bool fuzzy=false) +{ + static if (pattern.length > 0) + { + static if (pattern[0] == '\\') + { + static if (pattern.length > 1) + { + const char[] nextSlice = pattern[2 .. $]; + alias parseUntil!(nextSlice,terminator,fuzzy) next; + const char[] token = pattern[0 .. 2] ~ next.token; + const uint consumed = next.consumed+2; + } + else + { + pragma(msg,"Error: expected character to follow \\"); + static assert(false); + } + } + else static if (pattern[0] == terminator) + { + const char[] token=""; + const uint consumed = 1; + } + else + { + const char[] nextSlice = pattern[1 .. $]; + alias parseUntil!(nextSlice,terminator,fuzzy) next; + const char[] token = pattern[0..1] ~ next.token; + const uint consumed = next.consumed+1; + } + } + else static if (fuzzy) + { + const char[] token = ""; + const uint consumed = 0; + } + else + { + pragma(msg,"Error: expected " ~ + terminator ~ + " to terminate group expression"); + static assert(false); + } +} + +/** + * Parse contents of character class. + * Params: + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function + * consumed = number of characters in pattern[] parsed + */ + +template regexCompileCharClass2(char[] pattern) +{ + static if (pattern.length > 0) + { + static if (pattern.length > 1) + { + static if (pattern[1] == '-') + { + static if (pattern.length > 2) + { + alias testRange!(pattern[0..1], pattern[2..3]) termFn; + const uint thisConsumed = 3; + const char[] remaining = pattern[3 .. $]; + } + else // length is 2 + { + pragma(msg, + "Error: expected char following '-' in char class"); + static assert(false); + } + } + else // not '-' + { + alias testChar!(pattern[0..1]) termFn; + const uint thisConsumed = 1; + const char[] remaining = pattern[1 .. $]; + } + } + else + { + alias testChar!(pattern[0..1]) termFn; + const uint thisConsumed = 1; + const char[] remaining = pattern[1 .. $]; + } + alias regexCompileCharClassRecurse!(termFn,remaining) recurse; + alias recurse.fn fn; + const uint consumed = recurse.consumed + thisConsumed; + } + else + { + alias testEmpty!() fn; + const uint consumed = 0; + } +} + +/** + * Used to recursively parse character class. + * Params: + * termFn = generated function up to this point + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function including termFn and + * parsed character class + * consumed = number of characters in pattern[] parsed + */ + +template regexCompileCharClassRecurse(alias termFn,char[] pattern) +{ + static if (pattern.length > 0 && pattern[0] != ']') + { + alias regexCompileCharClass2!(pattern) next; + alias testOr!(termFn,next.fn,pattern) fn; + const uint consumed = next.consumed; + } + else + { + alias termFn fn; + const uint consumed = 0; + } +} + +/** + * At start of character class. Compile it. + * Params: + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function + * consumed = number of characters in pattern[] parsed + */ + +template regexCompileCharClass(char[] pattern) +{ + static if (pattern.length > 0) + { + static if (pattern[0] == ']') + { + alias testEmpty!() fn; + const uint consumed = 0; + } + else + { + alias regexCompileCharClass2!(pattern) charClass; + alias charClass.fn fn; + const uint consumed = charClass.consumed; + } + } + else + { + pragma(msg,"Error: expected closing ']' for character class"); + static assert(false); + } +} + +/** + * Look for and parse '*' postfix. + * Params: + * test = function compiling regex up to this point + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function + * consumed = number of characters in pattern[] parsed + */ + +template regexCompilePredicate(alias test, char[] pattern) +{ + static if (pattern.length > 0 && pattern[0] == '*') + { + alias testZeroOrMore!(test) fn; + const uint consumed = 1; + } + else + { + alias test fn; + const uint consumed = 0; + } +} + +/** + * Parse escape sequence. + * Params: + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function + * consumed = number of characters in pattern[] parsed + */ + +template regexCompileEscape(char[] pattern) +{ + static if (pattern.length > 0) + { + static if (pattern[0] == 's') + { + // whitespace char + alias testRange!("\x00","\x20") fn; + } + else static if (pattern[0] == 'w') + { + //word char + alias testWordChar!() fn; + } + else + { + alias testChar!(pattern[0 .. 1]) fn; + } + const uint consumed = 1; + } + else + { + pragma(msg,"Error: expected char following '\\'"); + static assert(false); + } +} + +/** + * Parse and compile regex represented by pattern[]. + * Params: + * pattern[] = rest of pattern to compile + * Output: + * fn = generated function + */ + +template regexCompile(char[] pattern) +{ + static if (pattern.length > 0) + { + static if (pattern[0] == '[') + { + const char[] charClassToken = + parseUntil!(pattern[1 .. $],']').token; + alias regexCompileCharClass!(charClassToken) charClass; + const char[] token = pattern[0 .. charClass.consumed+2]; + const char[] next = pattern[charClass.consumed+2 .. $]; + alias charClass.fn test; + } + else static if (pattern[0] == '\\') + { + alias regexCompileEscape!(pattern[1..pattern.length]) escapeSequence; + const char[] token = pattern[0 .. escapeSequence.consumed+1]; + const char[] next = + pattern[escapeSequence.consumed+1 .. $]; + alias escapeSequence.fn test; + } + else + { + const char[] token = parseTextToken!(pattern); + static assert(token.length > 0); + const char[] next = pattern[token.length .. $]; + alias testText!(token) test; + } + + alias regexCompilePredicate!(test, next) term; + const char[] remaining = next[term.consumed .. next.length]; + + alias regexCompileRecurse!(term,remaining).fn fn; + } + else + alias testEmpty!() fn; +} + +template regexCompileRecurse(alias term,char[] pattern) +{ + static if (pattern.length > 0) + { + alias regexCompile!(pattern) next; + alias testUnion!(term.fn, next.fn) fn; + } + else + alias term.fn fn; +} + +/// Utility function for parsing +template isSpecial(char[] pattern) +{ + static if ( + pattern[0] == '*' || + pattern[0] == '+' || + pattern[0] == '?' || + pattern[0] == '.' || + pattern[0] == '[' || + pattern[0] == '{' || + pattern[0] == '(' || + pattern[0] == ')' || + pattern[0] == '$' || + pattern[0] == '^' || + pattern[0] == '\\' + ) + const isSpecial = true; + else + const isSpecial = false; +} ++ + References+ +[1] D programming language, + see http://www.digitalmars.com/d/ + + +[2] Don Clugston's π calculator, see + http://trac.dsource.org/projects/ddl/browser/trunk/meta/demo/calcpi.d + + +[3] Don Clugston's decimaldigit and itoa, + see http://trac.dsource.org/projects/ddl/browser/trunk/meta/conv.d + + +[4] Eric Niebler's Boost.Xpressive regular expression template + library is at http://boost-sandbox.sourceforge.net/libs/xpressive/doc/html/index.html + + +[5] Eric Anderton's Regular Expression template library + for D is at http://trac.dsource.org/projects/ddl/browser/trunk/meta/regex.d + + +Acknowledgements+ +I gratefully acknowledge the inspiration and assistance +of Don Clugston, Eric Anderton and Matthew Wilson. + + + + |
+
+
+
+
- Warnings+ · Overview+ + + · D for Win32 + + + · Win32 DLLs in D + + + · C .h to D Modules + + + · FAQ + + + · Style Guide + + + · Example: wc + + + · Future + + + · D Change Log + + + · Tech Tips + + + · Rationale + + + · Exception Safety + + + · Templates Revisited + + + · Warnings + + + · Glossary + + + · Acknowledgements + + + + Tools + + · DMD D Compiler + + + · GDC D Compiler + + + · Linker + + + · Profiler + + + · Code Coverage + + + · DMD Script Shell + + + + Community + + + · News + + + · Forum + + + · Announcements + + + · Learn + + + · D links + + + + Archives + + · digitalmars.D + + + · digitalmars.D.dtl + + + · digitalmars.D.announce + + + · digitalmars.D.dwt + + + · digitalmars.D.learn + + + · digitalmars.D.bugs + + + · D.gnu + + + · Old D + + + + + |
+
+
+WarningsDepending on one's point of view, warnings are either a symptom of broken language design or a useful 'lint' like tool to analyze @@ -51,10 +208,10 @@ where the result of such can be cast back into a smaller type, perhaps losing significant bits in the process: -- byte a,b,c; - ... - a = b + c;+ byte a,b,c;
+...
+a = b + c;
+
The b and c are both promoted to type int using
the default integral promotion rules. The result of the add is then
@@ -69,8 +226,8 @@
- char[10] a; - int length = 4; - ... - return a[length - 1]; // returns a[9], not a[3]+ char[10] a; +int length = 4; +... +return a[length - 1]; // returns a[9], not a[3] +The warning can be resolved by: @@ -149,15 +306,16 @@ warning - no return at end of functionConsider the following: -- int foo(int k, Collection c) - { - foreach (int x; c) - { - if (x == k) - return x + 1; - } - }+ + int foo(int k, Collection c) +{ + foreach (int x; c) + { + if (x == k) + return x + 1; + } +} +and assume that the nature of the algorithm is that x will always be found in c, so the foreach never falls @@ -190,16 +348,16 @@ returning some arbitrary value (after all, it will never be executed): - - int foo(int k, Collection c) - { - foreach (int x; c) - { - if (x == k) - return x + 1; - } - return 0; // suppress warning about no return statement - }+ int foo(int k, Collection c) +{ + foreach (int x; c) + { + if (x == k) + return x + 1; + } + return 0; // suppress warning about no return statement +} +While doing this is surprisingly common, and happens when the programmer is inexperienced or in a hurry, it is a @@ -219,16 +377,16 @@ - int foo(int k, Collection c) - { - foreach (int x; c) - { - if (x == k) - return x + 1; - } - assert(0); - }+ int foo(int k, Collection c) +{ + foreach (int x; c) + { + if (x == k) + return x + 1; + } + assert(0); +} +Now, if the foreach does fall through, the error will be detected. Furthermore, it is self-documenting. @@ -236,16 +394,16 @@ - int foo(int k, Collection c) - { - foreach (int x; c) - { - if (x == k) - return x + 1; - } - throw new MyErrorClass("fell off the end of foo()"); - }+ int foo(int k, Collection c) +{ + foreach (int x; c) + { + if (x == k) + return x + 1; + } + throw new MyErrorClass("fell off the end of foo()"); +} +@@ -254,36 +412,36 @@ Similar to the no return statement warning is the no default in a switch warning. Consider: - - switch (i) - { - case 1: dothis(); break; - case 2: dothat(); break; - }+ switch (i) +{ + case 1: dothis(); break; + case 2: dothat(); break; +} +According to the D language semantics, this means the only possible values for i are 1 and 2. Any other values represent a bug in the program. To detect this bug, the compiler implements the switch as if it were written: - - switch (i) - { - case 1: dothis(); break; - case 2: dothat(); break; - default: throw new SwitchError(); - }+ switch (i) +{ + case 1: dothis(); break; + case 2: dothat(); break; + default: throw new SwitchError(); +} +This is quite different from C and C++ behavior, which is as if the switch were written: - - switch (i) - { - case 1: dothis(); break; - case 2: dothat(); break; - default: break; - }+ switch (i) +{ + case 1: dothis(); break; + case 2: dothat(); break; + default: break; +} +The potential for bugs with that is high, as it is a common error to accidentally omit a case, or to add a new value in one part of @@ -297,13 +455,13 @@
|
+ + + diff -uNr dmd-0.149/dmd/html/d/wc.html dmd-0.150/dmd/html/d/wc.html --- dmd-0.149/dmd/html/d/wc.html 2006-03-03 08:22:14.000000000 +0100 +++ dmd-0.150/dmd/html/d/wc.html 2006-03-18 10:52:52.000000000 +0100 @@ -25,7 +25,7 @@ | Comments -