[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.27 Attribute Syntax

This section describes the syntax with which __attribute__ may be used, and the constructs to which attribute specifiers bind, for the C language. Some details may vary for C++ and Objective C. Because of infelicities in the grammar for attributes, some forms described here may not be successfully parsed in all cases.

See section 5.26 Declaring Attributes of Functions, for details of the semantics of attributes applying to functions. See section 5.33 Specifying Attributes of Variables, for details of the semantics of attributes applying to variables. See section 5.34 Specifying Attributes of Types, for details of the semantics of attributes applying to structure, union and enumerated types.

An attribute specifier is of the form __attribute__ ((attribute-list)). An attribute list is a possibly empty comma-separated sequence of attributes, where each attribute is one of the following:

An attribute specifier list is a sequence of one or more attribute specifiers, not separated by any other tokens.

An attribute specifier list may appear after the colon following a label, other than a case or default label. The only attribute it makes sense to use after a label is unused. This feature is intended for code generated by programs which contains labels that may be unused but which is compiled with `-Wall'. It would not normally be appropriate to use in it human-written code, though it could be useful in cases where the code that jumps to the label is contained within an #ifdef conditional.

An attribute specifier list may appear as part of a struct, union or enum specifier. It may go either immediately after the struct, union or enum keyword, or after the closing brace. It is ignored if the content of the structure, union or enumerated type is not defined in the specifier in which the attribute specifier list is used--that is, in usages such as struct __attribute__((foo)) bar with no following opening brace. Where attribute specifiers follow the closing brace, they are considered to relate to the structure, union or enumerated type defined, not to any enclosing declaration the type specifier appears in, and the type defined is not complete until after the attribute specifiers.

Otherwise, an attribute specifier appears as part of a declaration, counting declarations of unnamed parameters and type names, and relates to that declaration (which may be nested in another declaration, for example in the case of a parameter declaration). In future, attribute specifiers in some places may however apply to a particular declarator within a declaration instead; these cases are noted below. Where an attribute specifier is applied to a parameter declared as a function or an array, it should apply to the function or array rather than the pointer to which the parameter is implicitly converted, but this is not yet correctly implemented.

Any list of specifiers and qualifiers at the start of a declaration may contain attribute specifiers, whether or not such a list may in that context contain storage class specifiers. (Some attributes, however, are essentially in the nature of storage class specifiers, and only make sense where storage class specifiers may be used; for example, section.) There is one necessary limitation to this syntax: the first old-style parameter declaration in a function definition cannot begin with an attribute specifier, because such an attribute applies to the function instead by syntax described below (which, however, is not yet implemented in this case). In some other cases, attribute specifiers are permitted by this grammar but not yet supported by the compiler. All attribute specifiers in this place relate to the declaration as a whole. In the obsolescent usage where a type of int is implied by the absence of type specifiers, such a list of specifiers and qualifiers may be an attribute specifier list with no other specifiers or qualifiers.

An attribute specifier list may appear immediately before a declarator (other than the first) in a comma-separated list of declarators in a declaration of more than one identifier using a single list of specifiers and qualifiers. At present, such attribute specifiers apply not only to the identifier before whose declarator they appear, but to all subsequent identifiers declared in that declaration, but in future they may apply only to that single identifier. For example, in __attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void), the noreturn attribute applies to all the functions declared; the format attribute should only apply to d1, but at present applies to d2 as well (and so causes an error).

An attribute specifier list may appear immediately before the comma, = or semicolon terminating the declaration of an identifier other than a function definition. At present, such attribute specifiers apply to the declared object or function, but in future they may attach to the outermost adjacent declarator. In simple cases there is no difference, but, for example, in void (****f)(void) __attribute__((noreturn));, at present the noreturn attribute applies to f, which causes a warning since f is not a function, but in future it may apply to the function ****f. The precise semantics of what attributes in such cases will apply to are not yet specified. Where an assembler name for an object or function is specified (see section 5.37 Controlling Names Used in Assembler Code), at present the attribute must follow the asm specification; in future, attributes before the asm specification may apply to the adjacent declarator, and those after it to the declared object or function.

An attribute specifier list may, in future, be permitted to appear after the declarator in a function definition (before any old-style parameter declarations or the function body).

An attribute specifier list may appear at the start of a nested declarator. At present, there are some limitations in this usage: the attributes apply to the identifier declared, and to all subsequent identifiers declared in that declaration (if it includes a comma-separated list of declarators), rather than to a specific declarator. When attribute specifiers follow the * of a pointer declarator, they must presently follow any type qualifiers present, and cannot be mixed with them. The following describes intended future semantics which make this syntax more useful only. It will make the most sense if you are familiar with the formal specification of declarators in the ISO C standard.

Consider (as in C99 subclause 6.7.5 paragraph 4) a declaration T D1, where T contains declaration specifiers that specify a type Type (such as int) and D1 is a declarator that contains an identifier ident. The type specified for ident for derived declarators whose type does not include an attribute specifier is as in the ISO C standard.

If D1 has the form ( attribute-specifier-list D ), and the declaration T D specifies the type "derived-declarator-type-list Type" for ident, then T D1 specifies the type "derived-declarator-type-list attribute-specifier-list Type" for ident.

If D1 has the form * type-qualifier-and-attribute-specifier-list D, and the declaration T D specifies the type "derived-declarator-type-list Type" for ident, then T D1 specifies the type "derived-declarator-type-list type-qualifier-and-attribute-specifier-list Type" for ident.

For example, void (__attribute__((noreturn)) ****f)(); specifies the type "pointer to pointer to pointer to pointer to non-returning function returning void". As another example, char *__attribute__((aligned(8))) *f; specifies the type "pointer to 8-byte-aligned pointer to char". Note again that this describes intended future semantics, not current implementation.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

This document was generated by Vincent Chung on June, 26 2001 using texi2html