Note: This website is archived. For up-to-date information about D projects and development, please visit wiki.dlang.org.

Errata for 'Learn to Tango with D'

Chapter 2: D Fundamentals

Basic Types

Integral Types, p20

Unsigned types can represent only positive non-negative numbers.

Arrays

Strings, p30

A correction concerning this sample code:

char[4] s2 = "abcd"; // s2 is a static array. 
s2[0] = 'x';         // Again, this could cause a crash since s2 was initialized 
                     // with a string literal. 

With static (fixed-width) arrays, whether they are initialized with a string literal or not does not matter. A static array is a way of allocating storage for more than one value of a single type. In the example, s2 can be viewed as being a variable that has room for four char values. The string literal "abcd" is copied into that space. Assigning to an element of s2 does not affect the string literal, it only affects the storage allocated to s2, which is mutable.

D's static arrays behave like arrays in C, while D's dynamic arrays are very different.

Array Operations

Copying, p34

This example is wrong:

int[] x = [0, 1, 2, 3, 4]; 
int[] y = x;                  // All 5 elements of x are copied to y. 
int[] z = x[];                // All 5 elements of x are copied to z. 
y[0 .. 2] = x[1 .. 3];        // Same as y[1] = x[2];. 

Here is a version that actually does what comments and surrounding text says it does:

int[] x = [0, 1, 2, 3, 4]; 
int[] y = new int[x.length];  // Create another array of the same size as x.
y[] = x;                      // All 5 elements of x are copied to y.
y[] = x[];                    // Alternate syntax, which does exactly the same as the previous line.
  
y[1 .. 2] = x[2 .. 3];        // Same as y[1] = x[2];.

Note that creating a new dynamic array that's just a copy of another array can be done in a single statement using the .dup property.


Chapter 3: D’s Object-Oriented Features

Structs and Unions

Defining Unions, p58-59

Those of you not familiar with C might not know what a union is. It's simply a way to access the same piece of memory as different types. All the fields share the same memory, which means that assigning to one changes all the others too. Short explaination here.

Statements in this section that are wrong or misleading

If the members are of different sizes, the union will always be initialized to the size of the biggest member.

I'm not entirely sure how to interpret this, so to be on the safe side here's how it works:

  1. The union has a fixed size which is the same as that of its largest member, plus any padding needed for alignment.
  2. By default, the union is initialized with the default initializer of its first member. Any remaining space is filled with zeros.

If you assign a value of type char[] to a variable of type Error, errorMessage will be set to that value and errorCode zeroed.

errorCode is not zeroed, it's just overwritten with whatever is assigned to the errorMessage member.