Report a bug
If you spot a problem with this page, click here to create a Bugzilla issue.
Improve this page
Quickly fork, edit online, and submit a pull request for this page. Requires a signed-in GitHub account. This works well for small changes. If you'd like to make larger changes you may want to consider using a local clone.

core.attribute

This module contains UDA's (User Defined Attributes) either used in the runtime or special UDA's recognized by compiler.
Cheat Sheet
Attribute NameLinkageDescription
gnuAbiTagC++ Declares an ABI tag on a C++ symbol.
mustuse Ensures that values of a struct or union type are not discarded.
optionalObjective-C Makes an Objective-C interface method optional.
selectorObjective-C Attaches an Objective-C selector to a method.
weak Specifies that a global symbol should be emitted with weak linkage.
Authors:
Jacob Carlborg
enum weak;
Use this attribute to specify that a global symbol should be emitted with weak linkage. This is primarily useful in defining library functions that can be overridden by user code, though it can also be used with shared and static variables too.
The overriding symbol must have the same type as the weak symbol. In addition, if it designates a variable it must also have the same size and alignment as the weak symbol.
Quote from the LLVM manual: "Note that weak linkage does not actually allow the optimizer to inline the body of this function into callers because it doesn’t know if this definition of the function is the definitive definition within the program or whether it will be overridden by a stronger definition."
This attribute is only meaningful to the GNU and LLVM D compilers. The Digital Mars D compiler emits all symbols with weak linkage by default.
struct selector;
Use this attribute to attach an Objective-C selector to a method.
This is a special compiler recognized attribute, it has several requirements, which all will be enforced by the compiler:
  • The attribute can only be attached to methods or constructors which have Objective-C linkage. That is, a method or a constructor in a class or interface declared as
    extern(Objective-C)
    .
  • It cannot be attached to a method or constructor that is a template
  • The number of colons in the string need to match the number of arguments the method accept.
  • It can only be used once in a method declaration
Examples:
extern (Objective-C)
class NSObject
{
 this() @selector("init");
 static NSObject alloc() @selector("alloc");
 NSObject initWithUTF8String(in char* str) @selector("initWithUTF8String:");
 ObjcObject copyScriptingValue(ObjcObject value, NSString key, NSDictionary properties)
     @selector("copyScriptingValue:forKey:withProperties:");
}
enum optional;
Use this attribute to make an Objective-C interface method optional.
An optional method is a method that does not have to be implemented in the class that implements the interface. To safely call an optional method, a runtime check should be performed to make sure the receiver implements the method.
This is a special compiler recognized attribute, it has several requirements, which all will be enforced by the compiler:
  • The attribute can only be attached to methods which have Objective-C linkage. That is, a method inside an interface declared as extern (Objective-C)
  • It can only be used for methods that are declared inside an interface
  • It can only be used once in a method declaration
  • It cannot be attached to a method that is a template
Examples:
import core.attribute : optional, selector;

extern (Objective-C):

struct objc_selector;
alias SEL = objc_selector*;

SEL sel_registerName(in char* str);

extern class NSObject
{
    bool respondsToSelector(SEL sel) @selector("respondsToSelector:");
}

interface Foo
{
    @optional void foo() @selector("foo");
    @optional void bar() @selector("bar");
}

class Bar : NSObject
{
    static Bar alloc() @selector("alloc");
    Bar init() @selector("init");

    void bar() @selector("bar")
    {
    }
}

extern (D) void main()
{
    auto bar = Bar.alloc.init;

    if (bar.respondsToSelector(sel_registerName("bar")))
        bar.bar();
}
struct gnuAbiTag;
Use this attribute to declare an ABI tag on a C++ symbol.
ABI tag is an attribute introduced by the GNU C++ compiler. It modifies the mangled name of the symbol to incorporate the tag name, in order to distinguish from an earlier version with a different ABI.
This is a special compiler recognized attribute, it has a few requirements, which all will be enforced by the compiler:
  • There can only be one such attribute per symbol.
  • The attribute can only be attached to an extern(C++) symbol (struct, class, enum, function, and their templated counterparts).
  • The attribute cannot be applied to C++ namespaces. This is to prevent confusion with the C++ semantic, which allows it to be applied to namespaces.
  • The string arguments must only contain valid characters for C++ name mangling which currently include alphanumerics and the underscore character.
This UDA is not transitive, and inner scope do not inherit outer scopes' ABI tag. See examples below for how to translate a C++ declaration to D. Also note that entries in this UDA will be automatically sorted alphabetically, hence gnuAbiTag("c", "b", "a") will appear as @gnuAbiTag("a", "b", "c").
Examples:
// ---- foo.cpp
struct [[gnu::abi_tag ("tag1", "tag2")]] Tagged1_2
{
    struct [[gnu::abi_tag ("tag3")]] Tagged3
    {
        [[gnu::abi_tag ("tag4")]]
        int Tagged4 () { return 42; }
    }
}
Tagged1_2 inst1;
// ---- foo.d
@gnuAbiTag("tag1", "tag2") struct Tagged1_2
{
    // Notice the repetition
    @gnuAbiTag("tag1", "tag2", "tag3") struct Tagged3
    {
        @gnuAbiTag("tag1", "tag2", "tag3", "tag4") int Tagged4 ();
    }
}
extern __gshared Tagged1_2 inst1;
enum mustuse;
Use this attribute to ensure that values of a struct or union type are not discarded.
The value of an expression is considered to be discarded if
  • the expression is the top-level expression in a statement or the left-hand expression in a comma expression, and
  • the expression is not an assignment (=, +=, etc.), increment (++), or decrement (--) expression.
If the declaration of a struct or union type has the @mustuse attribute, the compiler will emit an error any time a value of that type would be discarded.
Currently, @mustuse is only recognized by the compiler when attached to struct and union declarations. To allow for future expansion, attaching @mustuse to a class, interface, enum, or function declaration is currently forbidden, and will result in a compile-time error. All other uses of @mustuse are ignored.
Examples:
@mustuse struct ErrorCode { int value; }

extern(C) ErrorCode doSomething();

void main()
{
    // error: would discard a value of type ErrorCode
    //doSomething();

    ErrorCode result;
    // ok: value is assigned to a variable
    result = doSomething();

    // ok: can ignore the value explicitly with a cast
    cast(void) doSomething();
}
enum standalone;
Use this attribute to indicate that a shared module constructor does not depend on any other module constructor being run first. This avoids errors on cyclic module constructors.
However, it is now up to the user to enforce safety. The module constructor must be marked @system as a result. Prefer to refactor the module constructor causing the cycle so it's in its own module if possible.
This is only allowed on shared static constructors, not thread-local module constructors.