Properties
Every type and expression has properties that can be queried:
Expression | Value |
---|---|
int.sizeof | yields 4 |
float.nan | yields the floating point nan (Not A Number) value |
(float).nan | yields the floating point nan value |
(3).sizeof | yields 4 (because 3 is an int) |
int.init | default initializer for int's |
int.mangleof | yields the string "i" |
int.stringof | yields the string "int" |
(1+2).stringof | yields the string "1 + 2" |
Property | Description |
---|---|
.init | initializer |
.sizeof | size in bytes (equivalent to C's sizeof(type)) |
.alignof | alignment size |
.mangleof | string representing the ‘mangled’ representation of the type |
.stringof | string representing the source representation of the type |
Property | Description |
---|---|
.init | initializer (0) |
.max | maximum value |
.min | minimum value |
Property | Description |
---|---|
.init | initializer (NaN) |
.infinity | infinity value |
.nan | NaN value |
.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 |
Property | Description |
---|---|
.classinfo | Information about the dynamic type of the class |
.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. For example:
int a; int b = 1; typedef int t = 2; t c; t d = cast(t)3; int.init // is 0 a.init // is 0 b.init // is 0 t.init // is 2 c.init // is 2 d.init // is 2 struct Foo { int a; int b = 7; } Foo.init.a // is 0 Foo.init.b // is 7
Note: .init produces a default initialized object, not default constructed. That means using .init is sometimes incorrect.
- 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 a; struct S { void foo() { a = 1; } // access a variable in enclosing scope } S s1; // OK. S() correctly initialize its frame pointer. S s2 = S(); // OK. same as s1 S s3 = S.init; // Bad. the frame pointer in s3 is null s3.foo(); // Access violation }
struct S { int a; @disable this(); this(int n) { a = n; } invariant { assert(a > 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.a == 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. Semantic analysis is not done for that expression. For example:
module test; import std.stdio; struct Foo { } enum Enum { RED } typedef int myint; void main() { writeln((1+2).stringof); // "1 + 2" writeln(Foo.stringof); // "Foo" writeln(test.Foo.stringof); // "Foo" writeln(int.stringof); // "int" writeln((int*[5][]).stringof); // "int*[5u][]" writeln(Enum.RED.stringof); // "cast(enum)0" writeln(test.myint.stringof); // "myint" writeln((5).stringof); // "5" }
Note: Using .stringof for code generation is not recommended, as the internal representation of a type or expression can change between different compiler versions.
Instead you should prefer to use the identifier trait, or one of the Phobos helper functions such as fullyQualifiedName.
.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 int foo() { return a.sizeof; // returns 4 } } void test() { int x = S.a.sizeof; // sets x to 4 }
.sizeof applied to a class object returns the size of the class reference, not the class instantiation.
.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.
.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.