Attributes (Using the GNU Compiler Collection (GCC))

### 6.4 Attributes Specific to GCC ¶

Attributes provide a mechanism to declare additional properties of functions, variables, types, and statements. For example, attributes can be used to control placement of objects in particular memory sections, or to specify properties that can allow the compiler to generate better code or diagnostics, such as declaring that a function never returns. GCC supports a large number of such attributes, which are documented in this section.

GCC provides two different ways to specify attributes: the traditional GNU syntax using ‘`__attribute__ ((...))`’ annotations, and the newer standard C and C++ syntax using ‘`[[...]]`’ with the ‘`gnu::`’ namespace prefix on attribute names. Both syntaxes are accepted in all supported C and C++ dialects. However, if you use the `-Wpedantic` option (see Options to Request or Suppress Warnings), GCC warns about uses of the standard attribute syntax in C dialects prior to C23 and C++ dialects prior to C++11, which did not include this feature. You can suppress these warnings by prefixing the attribute name with the `__extension__` keyword; See Alternate Keywords.

The traditional syntax is described in detail in GNU Attribute Syntax. Refer to the C or C++ standards for the exact rules regarding placement of standard attributes.

Here are some examples showing the use of attributes.

No matter which syntax is used, attributes in a variable declaration can be placed at the beginning of the declaration (in which case they apply to all declarators in the declaration), or after a particular declarator (applying only to that variable).

    [[gnu::aligned (16)]] int v1 = 0;
    int v2 __attribute__ ((aligned (16))) = 0;
    int v3 [[gnu::aligned (16)]] = 0;
    int v4 __attribute__ ((aligned (16))) = 0;

Attributes for a function declaration or definition can appear first in both syntaxes:

    [[gnu::section ("bar")]] extern void f1 (void);
    __attribute__ ((section ("bar"))) extern void f2 (void);

But, watch out for the common style of placing of attributes after the argument list when using the GNU syntax. With the standard syntax, attributes in this location are treated as modifying the type of the function rather than the function itself, or its name.

    extern void f3 (void) [[gnu::section ("bar")]];  /* Error!  */
    extern void f4 (void) __attribute__ ((section ("bar")));

An error is diagnosed on the declaration of `f3` because the `section` attribute can’t apply to types. To apply it correctly to the function, either put the attribute at the beginning of the declaration, or put it after the name of the function, like this:

    extern void f3 [[gnu::section ("bar")]] (void);

Typedefs follow the same attribute placement rules for other as other declarations. These declarations are all valid with similar meanings.

    [[gnu::unavailable]] typedef int *t1;
    typedef int *t2 [[gnu::unavailable]];
    __attribute__ ((unavailable)) typedef int *t3;
    typedef int *t4 __attribute__ ((unavailable));

Members of a struct, union, or C++ class follow similar rules for attribute placement as other declarations, but beware that many attributes intended for use in top-level declarations, such as those that specify linker attributes of symbols, do not make sense here.

Put attributes that apply to a `struct`, `union`, `class`, or `enum` type as a whole between the keyword and the type name:

    struct [[gnu::aligned (8)]] s1 { short f[3]; };
    struct __attribute__ ((aligned (8))) s2 { short f[3]; };

There are only a few attributes that apply to enumerators; those are placed directly after the enumerator name.

Statement attributes are placed before a statement or label. An attribute placed before an empty statement is a special case, an attribute declaration, with semantics that depend on the particular attribute. Otherwise statement attributes usually apply to the statement or label they prefix.

These two functions are equivalent:

    int foo1 (int x, int y)
    {
      [[gnu::assume (x == 42)]];
      return x + y;
    }

    int foo2 (int x, int y)
    {
      __attribute__((assume(x == 42)));
      return x + y;
    }

If you want to specify multiple attributes on the same entity, both syntaxes allow you to to list them in the same attribute specifier, separated by commas:

    [[gnu::section ("bar"), gnu::weak]]
    void g1 (void) { f1 (); }

    __attribute__ ((section ("bar"), weak))
    void g2 (void) { f2 (); }

Alternatively, you can use multiple attribute specifiers:

    [[gnu::section ("bar")]] [[gnu::weak]]
    void g3 (void) { f1 (); }

    __attribute__ ((section ("bar"))) __attribute__ ((weak))
    void g4 (void) { f2 (); }

In the sections that follow, either or both syntaxes may appear in code examples. All attributes can be used with both syntaxes even if only one is used in the examples for a given attribute.

Compatible attribute specifications on distinct declarations of the same entity are merged. An attribute specification that is not compatible with attributes already applied to a declaration of the same entity is ignored with a warning.

Every GNU-specific attribute has an alternate name that is prefixed and suffixed by two underscores; for example, the alternate name of `weak` is `__weak__`. These alternate names are useful in library header files in case they are included into files that have redefined the base name of the attribute as a preprocessor macro.

GCC also accepts the keyword `__attribute` as a synonym for `__attribute__`.

Some function attributes take one or more arguments that refer to the function’s parameters by their positions within the function parameter list. Such attribute arguments are referred to as positional arguments. Unless specified otherwise, positional arguments that specify properties of parameters with pointer types can also specify the same properties of the implicit C++ `this` argument in non-static member functions, and of parameters of reference to a pointer type. For ordinary functions, position one refers to the first parameter on the list. In C++ non-static member functions, position one refers to the implicit `this` pointer.

The same restrictions and effects apply to function attributes used with ordinary functions or C++ member functions.