Specifying Attributes of Types

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.

aligned ( alignment )
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 S or more_aligned_int will be allocated andaligned at least on a 8-byte boundary. On a SPARC, having allvariables of type struct S aligned to 8-byte boundaries allowsthe compiler to use the ldd and std (doubleword load andstore) instructions when copying one variable of type struct S toanother, thus improving run-time efficiency.

Note that the alignment of any given struct or union typeis 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 ofthe struct or union in question. This means that you caneffectively adjust the alignment of a struct or uniontype by attaching an aligned attribute 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 entire struct or union type.

As in the preceding example, you can explicitly specify the alignment(in bytes) that you wish the compiler to use for a given structor union type. 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 short is 2 bytes, thenthe size of the entire struct S type is 6 bytes. The smallestpower of two which is greater than or equal to that is 8, so thecompiler sets the alignment for the entire struct S type 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 aligned attribute can only increase the alignment; but youcan decrease it by specifying packed as well. See below.

Note that the effectiveness of aligned attributes 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 specifying aligned(16)in an __attribute__ will still only provide you with 8 bytealignment. See your linker documentation for further information.

packed
This attribute, attached to struct or union typedefinition, specifies that each member of the structure or union isplaced to minimize the memory required. When attached to an enumdefinition, it indicates that the smallest integral type should be used.

Specifying this attribute for struct and union types isequivalent to specifying the packed attribute on each of thestructure or union members. Specifying the -fshort-enumsflag on the line is equivalent to specifying the packedattribute on all enum definitions.

In the following example struct my_packed_struct's members arepacked closely together, but the internal layout of its s memberis not packed—to do that, struct my_unpacked_struct would 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,struct or union, not on a typedef which does notalso define the enumerated type, structure or union.

transparent_union
This attribute, attached to a union type 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 const onthe 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 thewait function must accept either a value of type int * tocomply with Posix, or a value of type union wait * to comply withthe 4.1BSD interface. If wait's parameter were void *,wait would 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 * or union wait *arguments to be passed, using the int * calling convention. The program can call wait with 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);
          }
     

unused
When attached to a type (including a union or a struct),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.
deprecated
The deprecated attribute 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 deprecated attribute can also be used for functions andvariables (see Function Attributes, see Variable Attributes.)

may_alias
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 char type. 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_a with short in 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 the notshared attribute 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::C is exported from the current DLL, but thevirtual table for C is not exported. (You can use__attribute__ instead of __declspec if you prefer, butmost Symbian OS code uses __declspec.)

5.32.2 i386 Type Attributes

Two attributes are currently defined for i386 configurations:ms_struct and gcc_struct

ms_struct gcc_struct
If packed is 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.

To specify multiple attributes, separate them by commas within thedouble parentheses: for example, `__attribute__ ((aligned (16),packed))'.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值