Properties
Common Properties
Every symbol, type, and expression has properties that can be queried:
Property | Description |
---|---|
.mangleof | string representing the ‘mangled’ representation of the type |
.stringof | string representing the source representation of the type |
Expression | Value |
---|---|
int.mangleof | yields the string "i" |
int.stringof | yields the string "int" |
(1+2).stringof | yields the string "1 + 2" |
Type Properties
Every type has properties that can be queried. Every expression also has these properties, which are equivalent to the properties of the expression's type. These properties are:
Property | Description |
---|---|
.init | initializer |
.sizeof | size in bytes |
.alignof | alignment size |
Expression | Value |
---|---|
int.init | yields 0 |
int.sizeof | yields 4 |
(3).sizeof | yields 4 (because 3 is an int) |
Numeric Properties
Property | Description |
---|---|
.max | maximum value |
.min | minimum value |
Property | Description |
---|---|
.infinity | infinity value |
.nan | NaN - Not a Number value (other NaN values can be produced) |
.dig | number of decimal digits of precision |
.epsilon | smallest increment to the value 1 |
.mant_dig | number of bits in mantissa |
.max_10_exp | maximum int value such that 10max_10_exp is representable |
.max_exp | maximum int value such that 2max_exp-1 is representable |
.min_10_exp | minimum int value such that 10min_10_exp is representable as a normalized value |
.min_exp | minimum int value such that 2min_exp-1 is representable as a normalized value |
.max | largest representable value that's not infinity |
.min_normal | smallest representable normalized value that's not 0 |
.re | real part |
.im | imaginary part |
Expression | Value |
---|---|
float.nan | yields the floating point NaN value |
(2.5F).nan | yields the floating point NaN value |
Derived Type Properties
See:
User-Defined Type Properties
See:
.init Property
.init produces a constant expression that is the default initializer. If applied to a type, it is the default initializer for that type. If applied to a variable or field, it is the default initializer for that variable or field's type. The default values for different kinds of types are described below:
Type | .init Value |
---|---|
char | '\xff' |
dchar | '\xffff' |
wchar | '\xffff' |
Enum | first member value |
Integers | 0 |
Floating Point | NaN |
Reference Types | null |
Structs | each field's default value |
Unions | first member value |
int a; int b = 1; static assert(int.init == 0); static assert(a.init == 0); static assert(b.init == 0); struct Foo { int a; int b = 7; } static assert(Foo.init.a == 0); static assert(Foo.init.b == 7);
.init vs Default Construction
Note that .init produces a default initialized object, not a default constructed one. If there is a default constructor for an object, it may produce a different value.
- If T is a nested struct, the context pointer in T.init is null.
- If T is a struct which has @disable this();, T.init might return a logically incorrect object.
void main() { int x; struct S { void foo() { x = 1; } // access x in enclosing scope via context pointer } S s1; // OK. S() correctly initialize its context pointer. S s2 = S(); // OK. same as s1 s1.foo(); // OK S s3 = S.init; // Bad. the context pointer in s3 is null s3.foo(); // Access violation }
struct S { int x; @disable this(); this(int n) { x = n; } invariant { assert(x > 0); } void check() {} } void main() { //S s1; // Error: variable s1 initializer required for type S //S s2 = S(); // Error: constructor S.this is not callable // because it is annotated with @disable S s3 = S.init; // Bad. s3.x == 0, and it violates the invariant of S s3.check(); // Assertion failure }
.stringof Property
.stringof produces a constant string that is the source representation of its prefix. If applied to a type, it is the string for that type. If applied to an expression, it is the source representation of that expression. The expression will not be evaluated.
module test; import std.stdio; struct Dog { } enum Color { Red } int i = 4; void main() { writeln((1+2).stringof); // "1 + 2" writeln(test.stringof); // "module test" writeln(Dog.stringof); // "Dog" writeln(int.stringof); // "int" writeln((int*[5][]).stringof); // "int*[5][]" writeln(Color.Red.stringof); // "Red" writeln((5).stringof); // "5" writeln((++i).stringof); // "i += 1" assert(i == 4); // `++i` was not evaluated }
.sizeof Property
e.sizeof gives the size in bytes of the expression e.
When getting the size of a member, it is not necessary for there to be a this object:
struct S { int a; } static assert(S.a.sizeof == 4); static assert(Object.sizeof == (void*).sizeof);
.sizeof applied to a class object returns the size of the class reference, not the class instantiation.
See also: __traits(classInstanceSize).
.alignof Property
.alignof gives the aligned size of an expression or type. For example, an aligned size of 1 means that it is aligned on a byte boundary, 4 means it is aligned on a 32 bit boundary.
See the align attribute for an example.
.mangleof Property
Mangling refers to how a symbol is represented in text form in the generated object file. .mangleof returns a string literal of the representation of the type or symbol it is applied to. The mangling of types and symbols with D linkage is defined by Name Mangling.
- whether a leading underscore is added to a symbol
- the mangling of types and symbols with non-D linkage. For C and C++ linkage, this will typically match what the associated C or C++ compiler does.
.classinfo Property
.classinfo provides information about the dynamic type of a class object. It returns a reference to type object.TypeInfo_Class.
.classinfo applied to an interface gives the information for the interface, not the class it might be an instance of.
User-Defined Properties
User-defined properties can be created using Property Functions.