Attribute Syntax, attributesyntax
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.
There are some problems with the semantics of attributes in C ++. for example, there are no manglings for attributes, although they may affect code generation, so problems may arise when attributed types are used in conjunction with templates or overloading. similarly,typeid
Does not distinguish between types with different attributes. Support for attributes in C ++ may be restricted in future to attributes on declarations only, but not on nested declarators.
See Function Attributes, for details of the semantics of attributes applying to functions. see Variable Attributes, for details of the semantics of attributes applying to variables. see Type Attributes, for details of the semantics of attributes applying to structure, union and enumerated types.
AnAttribute specifierIs of the form__attribute__ ((
Attribute-list))
.Attribute listIs a possibly empty comma-separated sequenceAttributes, Where each attribute is one of the following:
- Empty. Empty attributes are ignored.
- A word (which may be an identifier such
unused
, Or a reserved word suchconst
).
- A word, followed by, in parentheses, parameters for the attribute. These parameters take one of the following forms:
- An identifier. For example,
mode
Attributes use this form.
- An identifier followed by a comma and a non-empty comma-separated list of expressions. For example,
format
Attributes use this form.
- A possibly empty comma-separated list of expressions. For example,
format_arg
Attributes use this form with the list being a single integer constant expression, andalias
Attributes use this form with the list being a single string constant.
AnAttribute specifier listIs a sequence of one or more attribute specifiers, not separated by any other tokens.
In gnu c, an attribute specifier list may appear after the colon following a label, other thancase
Ordefault
Label. The only attribute it makes sense to use after a label isunused
. This feature is intended for code generated by programs which contains labels that may be unused but which is compiled-Wall. It wocould not normally be appropriate to use in it human-written code, though it cocould be useful in cases where the code that jumps to the label is contained within#ifdef
Conditional. gnu c ++ only permits attributes on labels if the attribute specifier is immediately followed by a semicolon (I. e ., the label applies to an empty statement ). if the semicolon is missing, C ++ label attributes are ambiguous, as it is permissible for a declaration, which cocould begin with an attribute list, to be labeled in C ++. declarations cannot be labeled in C90 or C99, so the ambiguity does not arise there.
An attribute specifier list may appear as part ofstruct
,union
Orenum
Specifier. It may go either immediately afterstruct
,union
Orenum
Keyword, or after the closing brace. the former syntax is preferred. 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), or to a particle declarator within a declaration. where an attribute specifier is applied to a parameter declared as a function or an array, it shocould 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 in attribute specifiers, whether or not such a list may in that context contain storage class specifiers. (Some attributes, however, are essential 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 typeint
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.
At present, the first parameter in a function prototype must have some type specifier which is not an attribute specifier; this resolves an ambiguity in the interpretationvoid f(int (__attribute__((foo)) x))
, But is subject to change. at present, if the parentheses of a function declarator contain only attributes then those attributes are ignored, rather than yielding an error or warning or implying a single parameter of type int, but this is subject to change.
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. such attribute specifiers apply only to the identifier before whose declarator they appear. for example, in
__attribute__((noreturn)) void d0 (void), __attribute__((format(printf, 1, 2))) d1 (const char *, ...), d2 (void)
Thenoreturn
Attribute applies to all the functions declared;format
Attribute only appliesd1
.
An attribute specifier list may appear immediately before the comma,=
Or semicolon terminating the declaration of an identifier other than a function definition. such attribute specifiers apply to the declared object or function. where an attacker name for an object or function is specified (see Asm Labels), the attribute must followasm
Specification.
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 ).
Attribute specifiers may be mixed with type qualifiers appearing inside[]
Of a parameter array declarator, in the C99 construct by which such qualifiers are applied to the pointer to which the array is implicitly converted. such attribute specifiers apply to the pointer, not to the array, but at present this is not implemented and they are ignored.
An attribute specifier list may appear at the start of a nested declarator. at present, there are some limitations in this usage: the attributes correctly apply to the declarator, but for most individual attributes the semantics this implies are not implemented. when attribute specifiers follow*
Of a pointer declarator, they may be mixed with any type qualifiers present. the following describes the formal semantics of this syntax. 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 declarationT D1
, WhereT
Contains declaration specifiers that specify a typeType(Suchint
) AndD1
Is a declarator that contains an identifierIdent. The type specifiedIdentFor derived declarators whose type does not include an attribute specifier is as in the iso c standard.
IfD1
Has the form(
Attribute-specifier-list D )
, And the declarationT D
Specifies the type"Derived-declarator-type-list Type"Ident, ThenT D1
Specifies the type"Derived-declarator-type-list Attribute-specifier-list Type"Ident.
IfD1
Has the form*
Type-qualifier-and-attribute-specifier-list D
, And the declarationT D
Specifies the type"Derived-declarator-type-list Type"Ident, ThenT D1
Specifies the type"Derived-declarator-type-list Type-qualifier-and-attribute-specifier-listPointerType"Ident.
For example,
void (__attribute__((noreturn)) ****f) (void);
Specifies the type "pointer to non-returning function returningvoid
". As another example,
char *__attribute__((aligned(8))) *f;
Specifies the type "pointer to 8-byte-aligned pointerchar
". Note again that this does not work with most attributes; for example, the usage'AlignedAnd'Noreturn'Bubutes given above is not yet supported.
For compatibility with existing code written for compiler versions that did not implement attributes on nested declarators, some laxity is allowed in the placing of attributes. if an attribute that only applies to types is applied to a declaration, it will be treated as applying to the type of that declaration. if an attribute that only applies to declarations is applied to the type of a declaration, it will be treated as applying to that declaration; and, for compatibility with code placing the attributes immediately before the identifier declared, such an attribute applied to a function return type will be treated as applying to the function type, and such an attribute applied to an array element type will be treated as applying to the array type. if an attribute that only applies to function types is applied to a pointer-to-function type, it will be treated as applying to the pointer target type; if such an attribute is applied to a function return type that is not a pointer-to-function type, it will be treated as applying to the function type.
Explanation:
1. _ attribute _ (alias): declares an alias for a symbol.
return-type newname([arguments-list]) __attribute__((alias("oldname")))
Oldname: original function name newname: alias
Implementation of _ strong_alias macro in glibc
Example
#include <stdio.h>#include <stdlib.h> void foo(){ printf("\nInside %s\n",__FUNCTION__);} void _foo() __attribute__((alias("foo"))); //@Author : forestint main(int args,char ** argv){ _foo(); return EXIT_SUCCESS;}
Run
2. _ attribute _ (deprecated (MSG): deprecated, obsolete. If the deprecated attribute function is used anywhere in the source file, the compiler will issue a warning.
Example
# Include <stdio. h> # include <stdlib. h> _ attribute _ (deprecated ("foo function has been abandoned") void foo () {printf ("\ nInside % s \ n ", __function _);} void _ foo () _ attribute _ (alias ("foo"); // @ Author: forestint main (int args, char ** argv) {_ foo (); return EXIT_SUCCESS ;}
Compile
3. _ attribute _ (format (archetype, string-index, first-to-check): format attribute provides, check strfmon type function parameters and corresponding formats
_ Attribute _ (format (archetype, string-index, first-to-check): archtype: determines how format string will be interpreted. the interpreted type should be printf, scanf, strftime, gnu_printf, gnu_scanf, gnu_strftime .. (You can also use _ printf __,__ scanf __,__ strftime like glibc... the start and end of the line below ). string-index: the number of function parameters increases from left to right by 1, 2, and 3. string-index is the serial number of fmt. first-to-check: the first parameter in the parameter list to be compared with the fmt Format.
There are many usage of format attribute in glibc:
Example
#include <stdio.h>#include <stdlib.h> void foo(const char *fmt,...) \ __attribute__((__format__(__printf__,1,2))); //@Author : forestint main(int args,char ** argv){ //@test foo("\n%d %d","test_a","test_b"); return EXIT_SUCCESS;} void foo(const char *fmt,...){ /*do nothing*/}
Compile
4. _ attribute _ (weak): weak symbol, weak symbol. if two identical global symbols exist, a redefinition error is thrown. if weak attribute is used, when both weak symbol and non-weak symbol exist, linker uses non-weak symbol. if only weak symbol exists, only weak symbol is used.