Programming in D – Tutorial and Reference
Ali Çehreli

Other D Resources

Fundamental Types

We have seen that the brain of a computer is the CPU. Most of the tasks of a program are performed by the CPU and the rest are dispatched to other parts of the computer.

The smallest unit of data in a computer is called a bit. The value of a bit can be either 0 or 1.

Since a type of data that can hold only the values 0 and 1 would have very limited use, the CPU supports larger data types that are combinations of more than one bit. As an example, a byte usually consists of 8 bits. If an N-bit data type is the most efficient data type supported by a CPU, we consider it to be an N-bit CPU: as in 32-bit CPU, 64-bit CPU, etc.

The data types that the CPU supports are still not sufficient: they can't represent higher level concepts like name of a student or a playing card. Likewise, D's fundamental data types are not sufficient to represent many higher level concepts. Such concepts must be defined by the programmer as structs and classes by taking advantage of fundamental types. We will see structs and classes in later chapters.

D's fundamental types are similar to the fundamental types of many other languages. We will see more information about these types in the upcoming chapters.

Logical expression type

This is the type that is used in logical expressions. It takes the value of true for truth and false for falsity:

Type Definition Initial Value
bool Boolean type false
Integer types

Integers are numbers that don't have fractional parts. For example, 3 is an integer but 3.5 is not.

Types that can have negative and positive values are signed types. The names of these types come from the negative sign. Types that can have only positive values are unsigned types. The u at the beginning of the name of these types comes from unsigned.

Type Definition Initial Value
byte signed 8 bits 0
ubyte unsigned 8 bits 0
short signed 16 bits 0
ushort unsigned 16 bits 0
int signed 32 bits 0
uint unsigned 32 bits 0
long signed 64 bits 0L
ulong unsigned 64 bits 0LU
Floating point types

Floating point types are the types that can represent values with fractions as in 1.25. The precision of floating point calculations are directly related to the bit count of the type: higher the bit count, more precise the results are. Only floating point types can represent fractions; integer types like int can only represent whole values like 1 and 2.

Unlike integers, there are special values for floating point types that represent invalid values. These special values are written as properties as .nan and are short for "not a number".

Type Definition Initial Value
float 32 bits float.nan
double 64 bits double.nan
real at least 64 bits but can be more
if the hardware provides more
real.nan
Character types

These types are used for representing letters of alphabets and other symbols of writing systems:

Type Definition Initial Value
char UTF-8 code unit 0xFF
wchar UTF-16 code unit 0xFFFF
dchar UTF-32 code unit
and Unicode code point
0x0000FFFF

In addition to the above, the keyword void represents having no type.

The keywords cent and ucent are reserved for future use to represent signed and unsigned 128 bit values.

Unless there is a reason not to, you can use int to represent whole values. To represent concepts that can have fractional values, consider double.

Properties of types

D types have properties that provide information about these types. Properties are accessed with a dot after the name of the type. For example, the sizeof property of int is accessed as int.sizeof. We will see only some of type properties in this chapter:

Here is a program that prints these properties for int:

import std.stdio;

void main() {
    writeln("Type           : ", int.stringof);
    writeln("Length in bytes: ", int.sizeof);
    writeln("Minimum value  : ", int.min);
    writeln("Maximum value  : ", int.max);
    writeln("Initial value  : ", int.init);
}

The output of the program is the following:

Type           : int
Length in bytes: 4
Minimum value  : -2147483648
Maximum value  : 2147483647
Initial value  : 0
size_t

You will come across the size_t type as well. size_t is not a separate type but an alias of an existing unsigned type. Its name comes from "size type". It is the most suitable type to represent concepts like size or count.

size_t is large enough to represent the number of bytes of the memory that a program can potentially be using. Its actual size depends on the system: uint on a 32-bit system and ulong on a 64-bit system. For that reason, ulong is larger than size_t on a 32-bit system.

You can use the .stringof property to see what size_t is an alias of on your system:

import std.stdio;

void main() {
    writeln(size_t.stringof);
}

The output of the program is the following on my system:

ulong
Exercise

Print the properties of other types. Notes: