2.1.2 Common Attributes

The following attributes are supported on most targets.

@(gcc.attributes.alloc_size (sizeArgIdx))
@(gcc.attributes.alloc_size (sizeArgIdx, numArgIdx))
@(gcc.attributes.alloc_size (sizeArgIdx, numArgIdx, zeroBasedNumbering))

The @alloc_size attribute may be applied to a function - or a function pointer variable - that returns a pointer and takes at least one argument of an integer or enumerated type. It indicates that the returned pointer points to memory whose size is given by the function argument at sizeArgIdx, or by the product of the arguments at sizeArgIdx and numArgIdx. Meaningful sizes are positive values less than ptrdiff_t.max. Unless zeroBasedNumbering is true, argument numbering starts at one for ordinary functions, and at two for non-static member functions.

If numArgIdx is less than 0, it is taken to mean there is no argument specifying the element count.

@alloc_size(1) void* malloc(size_t);
@alloc_size(3,2) void* reallocarray(void *, size_t, size_t);
@alloc_size(1,2) void* my_calloc(size_t, size_t, bool);
void malloc_cb(@alloc_size(1) void* function(size_t) ptr) { }

The @always_inline attribute inlines the function independent of any restrictions that otherwise apply to inlining. Failure to inline such a function is diagnosed as an error.

@always_inline int func();

The @cold attribute on functions is used to inform the compiler that the function is unlikely to be executed. The function is optimized for size rather than speed and on many targets it is placed into a special subsection of the text section so all cold functions appear close together, improving code locality of non-cold parts of program. The paths leading to calls of cold functions within code are considered to be cold too.

@cold int func();

The @flatten attribute is used to inform the compiler that every call inside this function should be inlined, if possible. Functions declared with attribute @noinline and similar are not inlined.

@flatten int func();

The @no_icf attribute prevents a function from being merged with another semantically equivalent function.

@no_icf int func();
@(gcc.attributes.no_sanitize ("sanitize_option"))

The @no_sanitize attribute on functions is used to inform the compiler that it should not do sanitization of any option mentioned in sanitize_option. A list of values acceptable by the -fsanitize option can be provided.

@no_sanitize("alignment", "object-size") void func1() { }
@no_sanitize("alignment,object-size") void func2() { }

The @noclone attribute prevents a function from being considered for cloning - a mechanism that produces specialized copies of functions and which is (currently) performed by interprocedural constant propagation.

@noclone int func();

The @noinline attribute prevents a function from being considered for inlining. If the function does not have side effects, there are optimizations other than inlining that cause function calls to be optimized away, although the function call is live. To keep such calls from being optimized away, put asm { ""; } in the called function, to serve as a special side effect.

@noinline int func();

The @noipa attribute disables interprocedural optimizations between the function with this attribute and its callers, as if the body of the function is not available when optimizing callers and the callers are unavailable when optimizing the body. This attribute implies @noinline, @noclone, and @no_icf attributes. However, this attribute is not equivalent to a combination of other attributes, because its purpose is to suppress existing and future optimizations employing interprocedural analysis, including those that do not have an attribute suitable for disabling them individually.

This attribute is supported mainly for the purpose of testing the compiler.

@noipa int func();

The @noplt attribute is the counterpart to option -fno-plt. Calls to functions marked with this attribute in position-independent code do not use the PLT in position-independent code.

In position-dependant code, a few targets also convert call to functions that are marked to not use the PLT to use the GOT instead.

@noplt int func();
@(gcc.attributes.optimize (arguments))

The @optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line. Valid arguments are constant non-negative integers and strings. Multiple arguments can be provided, separated by commas to specify multiple options. Each numeric argument specifies an optimization level. Each string argument that begins with the letter O refers to an optimization option such as -O0 or -Os. Other options are taken as suffixes to the -f prefix jointly forming the name of an optimization option.

Not every optimization option that starts with the -f prefix specified by the attribute necessarily has an effect on the function. The @optimize attribute should be used for debugging purposes only. It is not suitable in production code.

@optimize(2) double fn0(double x);
@optimize("2") double fn1(double x);
@optimize("s") double fn2(double x);
@optimize("Ofast") double fn3(double x);
@optimize("-O2") double fn4(double x);
@optimize("tree-vectorize") double fn5(double x);
@optimize("-ftree-vectorize") double fn6(double x);
@optimize("no-finite-math-only", 3) double fn7(double x);
@(gcc.attributes.register ("registerName"))

The @register attribute specifies that a local or __gshared variable is to be given a register storage-class in the C99 sense of the term, and will be placed into a register named registerName.

The variable needs to boiled down to a data type that fits the target register. It also cannot have either thread-local or extern storage. It is an error to take the address of a register variable.

@register("ebx") __gshared int ebx = void;
void func() { @register("r10") long r10 = 0x2a; }

The @restrict attribute specifies that a function parameter is to be restrict-qualified in the C99 sense of the term. The parameter needs to boil down to either a pointer or reference type, such as a D pointer, class reference, or a ref parameter.

void func(@restrict ref const float[16] array);
@(gcc.attributes.section ("sectionName"))

The @section attribute specifies that a function or variable lives in a particular section. For when you need certain particular functions to appear in special sections.

Some file formats do not support arbitrary sections so the section attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead.

@section("bar") extern void func();
@section("stack") ubyte[10000] stack;

The @simd attribute enables creation of one or more function versions that can process multiple arguments using SIMD instructions from a single invocation. Specifying this attribute allows compiler to assume that such versions are available at link time (provided in the same or another module). Generated versions are target-dependent and described in the corresponding Vector ABI document.

@simd double sqrt(double x);
@(gcc.attributes.simd_clones ("mask"))

The @simd_clones attribute is the same as @simd, but also includes a mask argument. Valid masks values are notinbranch or inbranch, and instructs the compiler to generate non-masked or masked clones correspondingly.

@simd_clones("notinbranch") double atan2(double y, double x);
@(gcc.attributes.symver ("arguments"))

The @symver attribute creates a symbol version on ELF targets. The syntax of the string parameter is "name@nodename". The name part of the parameter is the actual name of the symbol by which it will be externally referenced. The nodename portion should be the name of a node specified in the version script supplied to the linker when building a shared library. Versioned symbol must be defined and must be exported with default visibility.

Finally if the parameter is "name@@nodename" then in addition to creating a symbol version (as if "name@nodename" was used) the version will be also used to resolve name by the linker.

@symver("foo@VERS_1") int foo_v1();
@(gcc.attributes.target ("options"))

The @target attribute is used to specify that a function is to be compiled with different target options than specified on the command line. One or more strings can be provided as arguments, separated by commas to specify multiple options. Each string consists of one or more comma-separated suffixes to the -m prefix jointly forming the name of a machine-dependent option.

The target attribute can be used for instance to have a function compiled with a different ISA (instruction set architecture) than the default.

The options supported are specific to each target.

@target("arch=core2") void core2_func();
@target("sse3") void sse3_func();
@(gcc.attributes.target_clones ("options"))

The @target_clones attribute is used to specify that a function be cloned into multiple versions compiled with different target options than specified on the command line. The supported options and restrictions are the same as for @target attribute.

It also creates a resolver function that dynamically selects a clone suitable for current architecture. The resolver is created only if there is a usage of a function with @target_clones attribute.

@target_clones("sse4.1,avx,default") double func(double x);

The @used attribute, annotated to a function or variable, means that code must be emitted for the function even if it appears that the function is not referenced. This is useful, for example, when the function is referenced only in inline assembly.

@used __gshared int var = 0x1000;
@(gcc.attributes.visibility ("visibilityName"))

The @visibility attribute affects the linkage of the declaration to which it is attached. It can be applied to variables, types, and functions.

There are four supported visibility_type values: default, hidden, protected, or internal visibility.

@visibility("protected") void func() {  }

The @weak attribute causes a declaration of an external symbol to be emitted as a weak symbol rather than a global. This is primarily useful in defining library functions that can be overridden in user code, though it can also be used with non-function declarations. 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.

Weak symbols are supported for ELF targets, and also for a.out targets when using the GNU assembler and linker.

@weak int func() { return 1; }