$(DDOC $(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(SPEC_S Attributes,
$(DDOC_BLANKLINE )
$(HEADERNAV_TOC $(HEADERNAV_ITEM linkage, Linkage Attribute)
$(HEADERNAV_SUBITEMS align, $(D align) Attribute,
$(HEADERNAV_ITEM align_gc, GC Compatibility)
)
$(HEADERNAV_ITEM deprecated, $(D deprecated) Attribute)
$(HEADERNAV_SUBITEMS visibility_attributes, Visibility Attribute,
$(HEADERNAV_ITEM export, $(D export) Attribute)
$(HEADERNAV_ITEM package, $(D package) Attribute)
$(HEADERNAV_ITEM private, $(D private) Attribute)
$(HEADERNAV_ITEM protected, $(D protected) Attribute)
$(HEADERNAV_ITEM public, $(D public) Attribute)
)
$(HEADERNAV_SUBITEMS mutability, Mutability Attributes,
$(HEADERNAV_ITEM const, $(D const) Attribute)
$(HEADERNAV_ITEM immutable, $(D immutable) Attribute)
$(HEADERNAV_ITEM inout, $(D inout) Attribute)
)
$(HEADERNAV_SUBITEMS shared-storage, Shared Storage Attributes,
$(HEADERNAV_ITEM shared, $(D shared) Attribute)
$(HEADERNAV_ITEM gshared, $(D __gshared) Attribute)
$(HEADERNAV_ITEM synchronized, $(D @synchronized) Attribute)
)
$(HEADERNAV_ITEM disable, $(D @disable) Attribute)
$(HEADERNAV_ITEM safe, $(D @safe), $(D @trusted), and $(D @system) Attribute)
$(HEADERNAV_SUBITEMS function-attributes, Function Attributes,
$(HEADERNAV_ITEM nogc, $(D @nogc) Attribute)
$(HEADERNAV_ITEM property, $(D @property) Attribute)
$(HEADERNAV_ITEM nothrow, $(D nothrow) Attribute)
$(HEADERNAV_ITEM pure, $(D pure) Attribute)
$(HEADERNAV_ITEM ref, $(D ref) Attribute)
$(HEADERNAV_ITEM return, $(D return) Attribute)
)
$(HEADERNAV_ITEM static, $(D static) Attribute)
$(HEADERNAV_ITEM auto, $(D auto) Attribute)
$(HEADERNAV_SUBITEMS scope, $(D scope) Attribute,
$(HEADERNAV_ITEM scope-values, Scope Values)
$(HEADERNAV_ITEM scope-class-var, $(D scope) Class Instances)
)
$(HEADERNAV_SUBITEMS class-attributes, OOP Attributes,
$(HEADERNAV_ITEM abstract, $(D abstract) Attribute)
$(HEADERNAV_ITEM final, final
Attribute)
$(HEADERNAV_ITEM override, $(D override) Attribute)
)
$(HEADERNAV_ITEM mustuse-attribute, @mustuse
Attribute)
$(HEADERNAV_SUBITEMS uda, User-Defined Attributes,
$(HEADERNAV_ITEM getAttributes, __traits(getAttributes)
)
$(HEADERNAV_ITEM uda-usage, Usage)
$(HEADERNAV_ITEM uda-templates, Templates)
)
)
$(DDOC_BLANKLINE )
$(GRAMMAR $(GNAME AttributeSpecifier):
$(GLINK Attribute) $(D :)
$(GLINK Attribute) $(GLINK DeclarationBlock)
$(DDOC_BLANKLINE )
$(GNAME Attribute):
$(GLINK AlignAttribute)
$(GLINK AtAttribute)
$(GLINK DeprecatedAttribute)
$(GLINK FunctionAttributeKwd)
$(GLINK LinkageAttribute)
$(GLINK2 pragma, Pragma)
$(GLINK VisibilityAttribute)
$(RELATIVE_LINK2 abstract, $(D abstract))
$(RELATIVE_LINK2 auto, $(D auto))
$(RELATIVE_LINK2 const, $(D const))
$(RELATIVE_LINK2 final, final
)
$(RELATIVE_LINK2 gshared, $(D __gshared))
$(RELATIVE_LINK2 linkage, $(D extern))
$(RELATIVE_LINK2 immutable, $(D immutable))
$(RELATIVE_LINK2 inout, $(D inout))
$(RELATIVE_LINK2 override, $(D override))
$(RELATIVE_LINK2 ref, $(D ref))
$(RELATIVE_LINK2 return, $(D return))
$(RELATIVE_LINK2 scope, $(D scope))
$(RELATIVE_LINK2 shared, $(D shared))
$(RELATIVE_LINK2 static, $(D static))
$(RELATIVE_LINK2 synchronized, synchronized
)
$(DDOC_BLANKLINE )
$(GNAME FunctionAttributeKwd):
$(RELATIVE_LINK2 nothrow, $(D nothrow))
$(RELATIVE_LINK2 pure, $(D pure))
$(DDOC_BLANKLINE )
$(GNAME AtAttribute):
$(D @) $(RELATIVE_LINK2 disable, $(D disable))
$(D @) $(RELATIVE_LINK2 nogc, $(D nogc))
$(D @) $(DDLINK spec/ob, Live Functions, live
)
$(GLINK Property)
$(D @) $(RELATIVE_LINK2 safe, $(D safe))
$(D @) $(RELATIVE_LINK2 safe, $(D system))
$(D @) $(RELATIVE_LINK2 safe, $(D trusted))
$(GLINK UserDefinedAttribute)
$(DDOC_BLANKLINE )
$(GNAME Property):
$(D @) $(RELATIVE_LINK2 property, $(D property))
$(DDOC_BLANKLINE )
$(GNAME DeclarationBlock):
$(GLINK2 module, DeclDef)
$(D {) $(GLINK2 module, DeclDefs)$(OPT ) $(D })
)
$(DDOC_BLANKLINE )
$(P Attributes are a way to modify one or more declarations.
The general forms are:
)
$(DDOC_BLANKLINE )
$(D_CODE attribute declaration; $(D_COMMENT // affects the declaration
)
attribute: $(D_COMMENT // affects all declarations until the end of
) $(D_COMMENT // the current scope
) declaration;
declaration;
...
attribute { $(D_COMMENT // affects all declarations in the block
) declaration;
declaration;
...
}
)
$(DDOC_BLANKLINE )
extern(C)
can be provided for all types of
declarations, including struct
or class
, even though
there is no corresponding match on the C
side. In that case,
the attribute is ignored. This behavior applies for nested
functions and nested variables as well. However, for static
member
methods and static
nested functions, adding extern(C)
will
change the calling convention, but not the mangling.
$(DDOC_BLANKLINE )
$(P D conventions are:)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD extern) (D):
)
$(DDOC_BLANKLINE )
$(P Windows API conventions are:)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD extern) (Windows):
$(D_KEYWORD void) *VirtualAlloc(
$(D_KEYWORD void) *lpAddress,
$(D_KEYWORD uint) dwSize,
$(D_KEYWORD uint) flAllocationType,
$(D_KEYWORD uint) flProtect
);
)
$(DDOC_BLANKLINE )
$(P The Windows convention is distinct from the C convention only on Win32 platforms,
where it is equivalent to the
$(LINK2 https://en.wikipedia.org/wiki/X86_calling_conventions, stdcall) convention.)
$(DDOC_BLANKLINE )
$(P Note that a $(DDSUBLINK spec/declaration, extern, lone $(D extern) keyword)
is used as a storage class.)
$(DDOC_BLANKLINE )
size_t
byte boundaries.)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
protected
, $(D public), or $(D export). They may be referred to as protection
attributes in documents predating $(LINK2 http://wiki.dlang.org/DIP22, DIP22).)
$(DDOC_BLANKLINE )
$(P Visibility participates in $(DDSUBLINK spec/module, name_lookup, symbol name lookup).
)
$(DDOC_BLANKLINE )
extern
is applied to it.)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD export) $(D_KEYWORD int) x = 3; $(D_COMMENT // definition, exporting `x`
)$(D_KEYWORD export) $(D_KEYWORD int) y; $(D_COMMENT // definition, exporting `y`
)$(D_KEYWORD export) $(D_KEYWORD extern) $(D_KEYWORD int) z; $(D_COMMENT // declaration, importing `z`
)
$(D_KEYWORD export) $(D_KEYWORD __gshared) h = 3; $(D_COMMENT // definition, exporting `h`
)$(D_KEYWORD export) $(D_KEYWORD __gshared) i; $(D_COMMENT // definition, exporting `i`
)$(D_KEYWORD export) $(D_KEYWORD extern) $(D_KEYWORD __gshared) $(D_KEYWORD int) j; $(D_COMMENT // declaration, importing `j`
))
$(DDOC_BLANKLINE )
$(P A function with a body is a definition, without a body is a declaration.)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD export) $(D_KEYWORD void) f() { } $(D_COMMENT // definition, exporting `f`
)$(D_KEYWORD export) $(D_KEYWORD void) g(); $(D_COMMENT // declaration, importing `g`
))
$(DDOC_BLANKLINE )
$(P In Windows terminology, $(I dllexport) means exporting a symbol from a DLL, and $(I dllimport) means
a DLL or executable is importing a symbol from a DLL.)
$(DDOC_BLANKLINE )
final
)
and cannot be overridden.
)
$(DDOC_BLANKLINE )
immutable
storage class))
$(LI $(DDSUBLINK spec/const3, immutable_type, $(D immutable) type qualifier)
)
)
shared
) attribute, $(D __gshared) provides no
safeguards against data races or other multi-threaded synchronization
issues. It is the responsibility of the programmer to ensure that
access to variables marked $(D __gshared) is synchronized correctly.)
$(DDOC_BLANKLINE )
$(P $(D __gshared) is disallowed in @safe
code.)
$(DDOC_BLANKLINE )
@disable this();
)
inside a struct disallows default construction.
)
$(DDOC_BLANKLINE )
$(P $(DDSUBLINK spec/struct, disable-copy, Disabling a struct copy constructor)
makes the struct not copyable.
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
ref
Storage Class).)
$(DDOC_BLANKLINE )
static
declaration does not apply to a particular
instance of an object, but to the type of the object. In
other words, it means there is no $(D this) reference.
)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_RUN $(D_CODE $(D_KEYWORD class) Foo
{
$(D_KEYWORD static) $(D_KEYWORD int) x;
$(D_KEYWORD static) $(D_KEYWORD int) bar() { $(D_KEYWORD return) x; }
$(D_KEYWORD int) foobar() { $(D_KEYWORD return) 7; }
}
Foo.x = 6; $(D_COMMENT // no instance needed
)$(D_KEYWORD assert)(Foo.bar() == 6);
$(D_COMMENT //Foo.foobar$(LPAREN)$(RPAREN ); // error, no instance of Foo
)
Foo f = $(D_KEYWORD new) Foo;
$(D_KEYWORD assert)(f.bar() == 6);
$(D_KEYWORD assert)(f.foobar() == 7);
)
)
$(DDOC_BLANKLINE )
$(P Static methods are never $(DDSUBLINK spec/function, virtual-functions, virtual).
)
$(P Static data has one instance per thread, not one per object.
)
$(DDOC_BLANKLINE )
$(P A static $(DDSUBLINK spec/function, nested, nested function)
or $(DDSUBLINK spec/struct, nested, type) cannot
access variables in the parent scope.)
$(DDOC_BLANKLINE )
$(P Inside a function, a $(DDSUBLINK spec/function, local-static-variables,
static local variable) persists after the function returns.)
$(DDOC_BLANKLINE )
$(P Static does not have the additional C meaning of being local
to a file. Use the $(RELATIVE_LINK2 VisibilityAttribute, private
)
attribute in D to achieve that.
For example:
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD module) foo;
$(D_KEYWORD int) x = 3; $(D_COMMENT // x is global
)$(D_KEYWORD private) $(D_KEYWORD int) y = 4; $(D_COMMENT // y is local to module foo
))
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
auto
attribute means return type inference.
See $(DDSUBLINK spec/function, auto-functions, Auto Functions).
)
$(DDOC_BLANKLINE )
scope
attribute signifies a variable's pointer values will not escape the scope that the variable is declared in.
)
$(DDOC_BLANKLINE )
$(P If the variable has a type that does not contain any indirections, the scope
attribute is ignored.
)
$(DDOC_BLANKLINE )
$(P When applied to a global variable, scope
is also ignored, since there is no scope larger than global scope that pointers could escape to.
)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD scope) $(D_KEYWORD int)* x; $(D_COMMENT // scope ignored, global variable
)
$(D_KEYWORD void) main()
{
$(D_COMMENT // scope static int* x; // cannot be both scope and static
) $(D_KEYWORD scope) $(D_KEYWORD float) y; $(D_COMMENT // scope ignored, no indirections
) $(D_KEYWORD scope) $(D_KEYWORD int)[2] z; $(D_COMMENT // scope ignored, static array is value type
) $(D_KEYWORD scope) $(D_KEYWORD int)[] w; $(D_COMMENT // scope dynamic array
)}
)
)
$(DDOC_BLANKLINE )
$(P When applied to a local variable with a type that has indirections,
its value may not be assigned to a variable with longer lifetime:
)
$(UL $(LI Variables outside the $(DDSUBLINK spec/statement, scope-statement, Scope Statement) that the variable is declared in)
$(LI Variables declared before the scope
variable, since local variables are destructed in the reverse order that they are declared in)
$(LI __gshared
or static
variables)
)
$(DDOC_BLANKLINE )
$(P Other operations implicitly assigning them to variables with longer lifetime are also disallowed:
)
$(UL $(LI Returning a scope
variable from a function)
$(LI Assigning a scope
variable to a non-scope parameter by calling a function)
$(LI Putting a scope
variable in an array literal)
)
$(P The scope
attribute is part of the variable declaration, not the type, and it only applies to the first level of indirection.
For example, it is impossible to declare a variable as a dynamic array of scope pointers, because scope
only applies to the .ptr
of the array itself, not its elements. scope
affects various types as follows:
)
$(DDOC_BLANKLINE )
$(TABLE_2COLS ,
Type of local variable, What scope
applies to
$(DDOC_BLANKLINE )
$(TROW Any $(DDSUBLINK spec/type, basic-data-types, Basic Data Type), nothing)
$(TROW $(DDSUBLINK spec/type, pointers, Pointer) T*
, the pointer value)
$(TROW $(DDSUBLINK spec/arrays, dynamic-arrays, Dynamic Array) T[]
, the .ptr
to the elements)
$(TROW $(DDSUBLINK spec/arrays, static-arrays, Static Array) T[n]
, each element T
)
$(TROW $(GLINK2 hash-map, Associative Array) K[V]
, the pointer to the implementation defined structure)
$(TROW struct
or union
, each of its member variables)
$(TROW function
pointer, the pointer value)
$(TROW $(DDSUBLINK spec/function, closures, delegate), both the .funcptr
and .ptr
(closure context) pointer values)
$(TROW class
or interface
, the class reference)
$(TROW $(GLINK2 enum, enum), the base type)
)
$(DDOC_BLANKLINE )
$(D_CODE $(D_KEYWORD struct) S
{
string str; $(D_COMMENT // note: string = immutable$(LPAREN)char$(RPAREN )[]
) string* strPtr;
}
string escape($(D_KEYWORD scope) S s, $(D_KEYWORD scope) S* sPtr, $(D_KEYWORD scope) string[2] sarray, $(D_KEYWORD scope) string[] darray)
{
$(D_KEYWORD return) s.str; $(D_COMMENT // invalid, scope applies to struct members
) $(D_KEYWORD return) *s.strPtr; $(D_COMMENT // valid, scope struct member is dereferenced
) $(D_KEYWORD return) sPtr.str; $(D_COMMENT // valid, struct pointer is dereferenced
) $(D_KEYWORD return) *sPtr.strPtr; $(D_COMMENT // valid, two pointers are dereferenced
) $(D_KEYWORD return) sarray[0]; $(D_COMMENT // invalid, scope applies to static array elements
) $(D_KEYWORD return) sarray[1]; $(D_COMMENT // invalid, ditto
) $(D_KEYWORD return) darray[0]; $(D_COMMENT // valid, scope applies to array pointer, not elements
)}
)
$(DDOC_BLANKLINE )
scope
value" is the value of a scope
variable, or a generated value pointing to stack allocated memory.
Such values are generated by $(DDSUBLINK spec/arrays, slicing, slicing) a static array
or creating $(DDSUBLINK spec/type, pointers, a pointer)
to a variable that is (or may be) allocated on the stack:
)
$(UL $(LI A function parameter)
$(LI A local variable)
$(LI A struct member accessed through the implicit this
parameter)
$(LI The return value of a $(DDSUBLINK spec/function, ref-functions, Ref Function))
)
$(DDOC_BLANKLINE )
$(P The variadic parameter from $(DDSUBLINK spec/function, typesafe_variadic_functions, Typesafe Variadic Functions) is also a scope value,
since the arguments are passed on the stack.
)
$(DDOC_BLANKLINE )
$(P When a local variable is assigned a scope
value, it is inferred scope
, even when the variable has an explicit type and does not use the auto
keyword.
)
$(DDOC_BLANKLINE )
$(D_CODE @safe:
$(D_KEYWORD ref) $(D_KEYWORD int)[2] identity($(D_KEYWORD return) $(D_KEYWORD ref) $(D_KEYWORD int)[2] x) {$(D_KEYWORD return) x;}
$(D_KEYWORD int)* escape($(D_KEYWORD int)[2] y, $(D_KEYWORD scope) $(D_KEYWORD int)* z)
{
$(D_KEYWORD int) x;
$(D_KEYWORD auto) xPtr = &x; $(D_COMMENT // inferred `scope int*`
) $(D_KEYWORD int)[] yArr = identity(y)[]; $(D_COMMENT // inferred `scope int[]`
) $(D_KEYWORD int)* zCopy = z; $(D_COMMENT // inferred `scope int*`
)
$(D_KEYWORD return) zCopy; $(D_COMMENT // error
)}
$(D_KEYWORD void) variadic($(D_KEYWORD int)[] a...)
{
$(D_KEYWORD int)[] x = a; $(D_COMMENT // inferred `scope int[]`
)}
$(D_KEYWORD void) main()
{
variadic(1, 2, 3);
}
)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD struct) S
{
$(D_KEYWORD int) x;
$(D_COMMENT // this method may be called on a stack-allocated instance of S
) $(D_KEYWORD void) f()
{
$(D_KEYWORD int)* p = &x; $(D_COMMENT // inferred `scope int* p`
) $(D_KEYWORD int)* q = &$(D_KEYWORD this).x; $(D_COMMENT // equivalent
) }
}
)
)
$(DDOC_BLANKLINE )
$(P $(DDSUBLINK spec/function, scope-parameters, Scope Parameters) are treated the same as scope local variables,
except that returning them is allowed when the function has $(DDSUBLINK spec/function, function-attribute-inference, Function Attribute Inference).
In that case, they are inferred as $(DDSUBLINK spec/function, return-scope-parameters, Return Scope Parameters).
)
$(DDOC_BLANKLINE )
scope
variable signifies the RAII
(Resource Acquisition Is Initialization) protocol.
This means that the destructor for an object is automatically called when the
reference to it goes out of scope. The destructor is called even
if the scope is exited via a thrown exception, thus $(D scope)
is used to guarantee cleanup.
)
$(P When a class is constructed with new
and assigned to a local scope
variable,
it may be allocated on the stack and permitted in a @nogc
context.
)
$(P If there is more than one scope
class variable going out of scope
at the same point, then the destructors are called in the reverse
order that the variables were constructed.
)
$(P Assignment to a $(D scope) variable with class type,
other than initialization, is not allowed, because that would complicate
proper destruction of the variable.
)
$(DDOC_BLANKLINE )
$(SPEC_RUNNABLE_EXAMPLE_COMPILE $(D_CODE $(D_KEYWORD import) core.stdc.stdio : puts;
$(D_KEYWORD class) C
{
~$(D_KEYWORD this)() @nogc { puts($(D_KEYWORD __FUNCTION__)); }
}
$(D_KEYWORD void) main() @nogc
{
{
$(D_KEYWORD scope) c0 = $(D_KEYWORD new) C(); $(D_COMMENT // allocated on the stack
) $(D_KEYWORD scope) c1 = $(D_KEYWORD new) C();
$(D_COMMENT //c1 = c0; // Error: cannot rebind scope variables
)
$(D_COMMENT // destructor of `c1` and `c0` are called here in that order
) }
puts($(D_STRING "bye"));
}
)
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
final
Attribute)final
) to prevent
subclassing.)
$(LI A class method can be declared $(DDSUBLINK spec/function, final, final
)
to prevent a derived class overriding it.)
$(LI Interfaces can define $(DDSUBLINK spec/interface, method-bodies, final
methods).)
)
$(DDOC_BLANKLINE )
@mustuse
Attribute)@mustuse
attribute is a compiler-recognized $(RELATIVE_LINK2 uda,
UDA) defined in the D runtime module $(DPLLINK phobos/core_attribute.html,
core.attribute
).
)
$(DDOC_BLANKLINE )
$(DDOC_BLANKLINE )
$(P An expression is considered to be discarded if and only if either of the
following is true:
)
$(UL $(LI it is the top-level $(GLINK2 expression, Expression) in an $(GLINK2 statement, ExpressionStatement), or
)
$(LI it is the $(GLINK2 expression, AssignExpression) on the left-hand
side of the comma in a $(GLINK2 expression, CommaExpression).
)
)
$(DDOC_BLANKLINE )
$(P It is a compile-time error to discard an expression if all of the
following are true:
)
$(DDOC_BLANKLINE )
$(UL $(LI it is not an assignment expression, an increment expression, or a
decrement expression; and
)
$(DDOC_BLANKLINE )
$(LI its type is a struct
or union
type whose declaration is
annotated with @mustuse
.
)
)
$(DDOC_BLANKLINE )
$(P "Assignment expression" means either a $(DDSUBLINK spec/expression, simple_assignment_expressions,
simple assignment expression) or an
$(DDSUBLINK spec/expression, assignment_operator_expressions, assignment
operator expression).
)
$(DDOC_BLANKLINE )
$(P "Increment expression" means a $(GLINK2 expression, UnaryExpression) or
$(GLINK2 expression, PostfixExpression) whose operator is ++
.
)
$(DDOC_BLANKLINE )
$(P "Decrement expression" means a $(GLINK2 expression, UnaryExpression) or
$(GLINK2 expression, PostfixExpression) whose operator is --
.
)
$(DDOC_BLANKLINE )
$(P It is a compile-time error to attach @mustuse
to a function
declaration or to any aggregate declaration other than a struct
or
union
declaration. The purpose of this rule is to reserve such usage
for possible future expansion.
)
$(DDOC_BLANKLINE )
e
, the attribute is an instance of struct Bar
which is
$(DDSUBLINK spec/struct, static_struct_init, statically initialized)
using its argument.)
$(DDOC_BLANKLINE )
$(P If there are multiple UDAs in scope for a declaration, they are concatenated:
)
$(DDOC_BLANKLINE )
$(D_CODE @(1)
{
@(2) $(D_KEYWORD int) a; $(D_COMMENT // has UDAs $(LPAREN)1, 2$(RPAREN )
) @($(D_STRING "string")) $(D_KEYWORD int) b; $(D_COMMENT // has UDAs $(LPAREN)1, "string"$(RPAREN )
)}
)
$(DDOC_BLANKLINE )
$(P A function parameter can have a UDA:)
$(D_CODE $(D_KEYWORD void) f(@(3) $(D_KEYWORD int) p);
)
$(DDOC_BLANKLINE )
__traits(getAttributes)
)