www.digitalmars.com

D Programming Language 1.0


Last update Tue Jan 25 20:54:15 2011

Structs & Unions

Whereas classes are reference types, structs are value types. Any C struct can be exactly represented as a D struct. In C++ parlance, a D struct is a POD (Plain Old Data) type, with a trivial constructors and destructors. Structs and unions are meant as simple aggregations of data, or as a way to paint a data structure over hardware or an external type. External types can be defined by the operating system API, or by a file format. Object oriented features are provided with the class data type.

A struct is defined to not have an identity; that is, the implementation is free to make bit copies of the struct as convenient.

Struct, Class Comparison Table
Feature struct class C struct C++ struct C++ class
value type X   X X X
reference type   X      
data members X X X X X
hidden members   X   X X
static members X X   X X
default member initializers X X      
bit fields     X X X
non-virtual member functions X X   X X
virtual member functions   X   X X
constructors   X   X X
destructors   X   X X
RAII   X   X X
assign overload       X X
literals X        
operator overloading X X   X X
inheritance   X   X X
invariants X X      
unit tests X X      
synchronizable   X      
parameterizable X X   X X
alignment control X X      
member protection X X   X X
default public X X X X  
tag name space     X X X
anonymous X   X X X
static constructor X X      
static destructor X X      
AggregateDeclaration:
	struct Identifier StructBody
	union Identifier StructBody
	struct Identifier ;
	union Identifier ;
	StructTemplateDeclaration
	UnionTemplateDeclaration

StructBody:
	{ }
	{ StructBodyDeclarations }

StructBodyDeclarations:
	StructBodyDeclaration
	StructBodyDeclaration StructBodyDeclarations

StructBodyDeclaration:
	DeclDef
	StructAllocator
	StructDeallocator


StructAllocator:
	ClassAllocator

StructDeallocator:
	ClassDeallocator

They work like they do in C, with the following exceptions:

Static Initialization of Structs

Static struct members are by default initialized to whatever the default initializer for the member is, and if none supplied, to the default initializer for the member's type. If a static initializer is supplied, the members are initialized by the member name, colon, expression syntax. The members may be initialized in any order. Initializers for statics must be evaluatable at compile time. Members not specified in the initializer list are default initialized.
struct X { int a; int b; int c; int d = 7;}
static X x = { a:1, b:2};	      // c is set to 0, d to 7
static X z = { c:4, b:5, a:2 , d:5};  // z.a = 2, z.b = 5, z.c = 4, z.d = 5
C-style initialization, based on the order of the members in the struct declaration, is also supported:
static X q = { 1, 2 };	  // q.a = 1, q.b = 2, q.c = 0, q.d = 7

Struct literals can also be used to initialize statics, but they must be evaluable at compile time.

static X q = S( 1, 2+3 );   // q.a = 1, q.b = 5, q.c = 0, q.d = 7

The static initializer syntax can also be used to initialize non-static variables, provided that the member names are not given. The initializer need not be evaluatable at compile time.

void test(int i)
{
    S s = { 1, i };   // q.a = 1, q.b = i, q.c = 0, q.d = 7
}

Static Initialization of Unions

Unions are initialized explicitly.
union U { int a; double b; }
static U u = { b : 5.0 };		// u.b = 5.0
Other members of the union that overlay the initializer, but occupy more storage, have the extra storage initialized to zero.

Dynamic Initialization of Structs

Structs can be dynamically initialized from another value of the same type:

struct S { int a; }
S t;      // default initialized
t.a = 3;
S s = t;  // s.a is set to 3

If opCall is overridden for the struct, and the struct is initialized with a value that is of a different type, then the opCall operator is called:

struct S
{   int a;

    static S opCall(int v)
    {	S s;
	s.a = v;
	return s;
    }

    static S opCall(S v)
    {	S s;
	s.a = v.a + 1;
	return s;
    }
}

S s = 3;	// sets s.a to 3
S t = s;	// sets t.a to 3, S.opCall(s) is not called

Struct Literals

Struct literals consist of the name of the struct followed by a parenthesized argument list:

struct S { int x; float y; }

int foo(S s) { return s.x; }

foo( S(1, 2) );   // set field x to 1, field y to 2

Struct literals are syntactically like function calls. If a struct has a member function named opCall, then struct literals for that struct are not possible. It is an error if there are more arguments than fields of the struct. If there are fewer arguments than fields, the remaining fields are initialized with their respective default initializers. If there are anonymous unions in the struct, only the first member of the anonymous union can be initialized with a struct literal, and all subsequent non-overlapping fields are default initialized.

Struct Properties

Struct Properties
.sizeof Size in bytes of struct
.alignof Size boundary struct needs to be aligned on
.tupleof Gets type tuple of fields

Struct Field Properties

Struct Field Properties
.offsetof Offset in bytes of field from beginning of struct




Forums | Comments |  D  | Search | Downloads | Home