Next: Alignment,Previous: Variable Attributes,Up: C Extensions
5.32 Specifying Attributes of Types
The keyword __attribute__ allows you to specify specialattributes of struct and union types when you define suchtypes. This keyword is followed by an attribute specification insidedouble parentheses. Six attributes are currently defined for types:aligned, packed, transparent_union, unused,deprecated and may_alias. Other attributes are defined forfunctions (see Function Attributes) and for variables(see Variable Attributes).
You may also specify any one of these attributes with `__'preceding and following its keyword. This allows you to use theseattributes in header files without being concerned about a possiblemacro of the same name. For example, you may use __aligned__instead of aligned.
You may specify the aligned and transparent_unionattributes either in a typedef declaration or just past theclosing curly brace of a complete enum, struct or union typedefinition and the packed attribute only past the closingbrace of a definition.
You may also specify attributes between the enum, struct or uniontag and the name of the type rather than after the closing brace.
See Attribute Syntax, for details of the exact syntax for usingattributes.
-
This attribute specifies a minimum alignment (in bytes) for variablesof the specified type. For example, the declarations:
struct S { short f[3]; } __attribute__ ((aligned (8))); typedef int more_aligned_int __attribute__ ((aligned (8)));force the compiler to insure (as far as it can) that each variable whosetype is
struct Sormore_aligned_intwill be allocated andaligned at least on a 8-byte boundary. On a SPARC, having allvariables of typestruct Saligned to 8-byte boundaries allowsthe compiler to use thelddandstd(doubleword load andstore) instructions when copying one variable of typestruct Stoanother, thus improving run-time efficiency.Note that the alignment of any given
structoruniontypeis required by the ISO C standard to be at least a perfect multiple ofthe lowest common multiple of the alignments of all of the members ofthestructorunionin question. This means that you caneffectively adjust the alignment of astructoruniontype by attaching analignedattribute to any one of the membersof such a type, but the notation illustrated in the example above is amore obvious, intuitive, and readable way to request the compiler toadjust the alignment of an entirestructoruniontype.As in the preceding example, you can explicitly specify the alignment(in bytes) that you wish the compiler to use for a given
structoruniontype. Alternatively, you can leave out the alignment factorand just ask the compiler to align a type to the maximumuseful alignment for the target machine you are compiling for. Forexample, you could write:struct S { short f[3]; } __attribute__ ((aligned));Whenever you leave out the alignment factor in an
alignedattribute specification, the compiler automatically sets the alignmentfor the type to the largest alignment which is ever used for any datatype on the target machine you are compiling for. Doing this can oftenmake copy operations more efficient, because the compiler can usewhatever instructions copy the biggest chunks of memory when performingcopies to or from the variables which have types that you have alignedthis way.In the example above, if the size of each
shortis 2 bytes, thenthe size of the entirestruct Stype is 6 bytes. The smallestpower of two which is greater than or equal to that is 8, so thecompiler sets the alignment for the entirestruct Stype to 8bytes.Note that although you can ask the compiler to select a time-efficientalignment for a given type and then declare only individual stand-aloneobjects of that type, the compiler's ability to select a time-efficientalignment is primarily useful only when you plan to create arrays ofvariables having the relevant (efficiently aligned) type. If youdeclare or use arrays of variables of an efficiently-aligned type, thenit is likely that your program will also be doing pointer arithmetic (orsubscripting, which amounts to the same thing) on pointers to therelevant type, and the code that the compiler generates for thesepointer arithmetic operations will often be more efficient forefficiently-aligned types than for other types.
The
alignedattribute can only increase the alignment; but youcan decrease it by specifyingpackedas well. See below.Note that the effectiveness of
alignedattributes may be limitedby inherent limitations in your linker. On many systems, the linker isonly able to arrange for variables to be aligned up to a certain maximumalignment. (For some linkers, the maximum supported alignment maybe very very small.) If your linker is only able to align variablesup to a maximum of 8 byte alignment, then specifyingaligned(16)in an__attribute__will still only provide you with 8 bytealignment. See your linker documentation for further information.
-
This attribute, attached to
structoruniontypedefinition, specifies that each member of the structure or union isplaced to minimize the memory required. When attached to anenumdefinition, it indicates that the smallest integral type should be used.Specifying this attribute for
structanduniontypes isequivalent to specifying thepackedattribute on each of thestructure or union members. Specifying the -fshort-enumsflag on the line is equivalent to specifying thepackedattribute on allenumdefinitions.In the following example
struct my_packed_struct's members arepacked closely together, but the internal layout of itssmemberis not packed—to do that,struct my_unpacked_structwould need tobe packed too.struct my_unpacked_struct { char c; int i; }; struct my_packed_struct __attribute__ ((__packed__)) { char c; int i; struct my_unpacked_struct s; };You may only specify this attribute on the definition of a
enum,structorunion, not on atypedefwhich does notalso define the enumerated type, structure or union.
-
This attribute, attached to a
uniontype definition, indicatesthat any function parameter having that union type causes calls to thatfunction to be treated in a special way.First, the argument corresponding to a transparent union type can be ofany type in the union; no cast is required. Also, if the union containsa pointer type, the corresponding argument can be a null pointerconstant or a void pointer expression; and if the union contains a voidpointer type, the corresponding argument can be any pointer expression. If the union member type is a pointer, qualifiers like
constonthe referenced type must be respected, just as with normal pointerconversions.Second, the argument is passed to the function using the callingconventions of the first member of the transparent union, not the callingconventions of the union itself. All members of the union must have thesame machine representation; this is necessary for this argument passingto work properly.
Transparent unions are designed for library functions that have multipleinterfaces for compatibility reasons. For example, suppose the
waitfunction must accept either a value of typeint *tocomply with Posix, or a value of typeunion wait *to comply withthe 4.1BSD interface. Ifwait's parameter werevoid *,waitwould accept both kinds of arguments, but it would alsoaccept any other pointer type and this would make argument type checkingless useful. Instead,<sys/wait.h>might define the interfaceas follows:typedef union { int *__ip; union wait *__up; } wait_status_ptr_t __attribute__ ((__transparent_union__)); pid_t wait (wait_status_ptr_t);This interface allows either
int *orunion wait *arguments to be passed, using theint *calling convention. The program can callwaitwith arguments of either type:int w1 () { int w; return wait (&w); } int w2 () { union wait w; return wait (&w); }With this interface,
wait's implementation might look like this:pid_t wait (wait_status_ptr_t p) { return waitpid (-1, p.__ip, 0); }
-
When attached to a type (including a
unionor astruct),this attribute means that variables of that type are meant to appearpossibly unused. GCC will not produce a warning for any variables ofthat type, even if the variable appears to do nothing. This is oftenthe case with lock or thread classes, which are usually defined and thennot referenced, but contain constructors and destructors that havenontrivial bookkeeping functions.
-
The
deprecatedattribute results in a warning if the typeis used anywhere in the source file. This is useful when identifyingtypes that are expected to be removed in a future version of a program. If possible, the warning also includes the location of the declarationof the deprecated type, to enable users to easily find furtherinformation about why the type is deprecated, or what they should doinstead. Note that the warnings only occur for uses and then onlyif the type is being applied to an identifier that itself is not beingdeclared as deprecated.typedef int T1 __attribute__ ((deprecated)); T1 x; typedef T1 T2; T2 y; typedef T1 T3 __attribute__ ((deprecated)); T3 z __attribute__ ((deprecated));results in a warning on line 2 and 3 but not lines 4, 5, or 6. Nowarning is issued for line 4 because T2 is not explicitlydeprecated. Line 5 has no warning because T3 is explicitlydeprecated. Similarly for line 6.
The
deprecatedattribute can also be used for functions andvariables (see Function Attributes, see Variable Attributes.)
-
Accesses to objects with types with this attribute are not subjected totype-based alias analysis, but are instead assumed to be able to aliasany other type of objects, just like the
chartype. See -fstrict-aliasing for more information on aliasing issues.Example of use:
typedef short __attribute__((__may_alias__)) short_a; int main (void) { int a = 0x12345678; short_a *b = (short_a *) &a; b[1] = 0; if (a == 0x12345678) abort(); exit(0); }If you replaced
short_awithshortin the variabledeclaration, the above program would abort when compiled with-fstrict-aliasing, which is on by default at -O2 orabove in recent GCC versions.5.32.1 ARM Type Attributes
On those ARM targets that support
dllimport(such as SymbianOS), you can use thenotsharedattribute to indicate that thevirtual table and other similar data for a class should not beexported from a DLL. For example:class __declspec(notshared) C { public: __declspec(dllimport) C(); virtual void f(); } __declspec(dllexport) C::C() {}In this code,
C::Cis exported from the current DLL, but thevirtual table forCis not exported. (You can use__attribute__instead of__declspecif you prefer, butmost Symbian OS code uses__declspec.)5.32.2 i386 Type Attributes
Two attributes are currently defined for i386 configurations:
ms_structandgcc_struct
-
If
packedis used on a structure, or if bit-fields are usedit may be that the Microsoft ABI packs them differentlythan GCC would normally pack them. Particularly when moving packeddata between functions compiled with GCC and the native Microsoft compiler(either via function call or as data in a file), it may be necessary to accesseither format.Currently -m[no-]ms-bitfields is provided for the Microsoft Windows X86compilers to match the native Microsoft compiler.
aligned (
alignment
)
packed
transparent_union
unused
deprecated
may_alias
ms_struct
gcc_struct
To specify multiple attributes, separate them by commas within thedouble parentheses: for example, `__attribute__ ((aligned (16),packed))'.
本文介绍了GCC编译器中用于指定类型的特殊属性,如aligned、packed等,并解释了这些属性如何影响结构体、联合体和枚举类型的内存布局及对齐方式。
4825

被折叠的 条评论
为什么被折叠?



