[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]  

Specifying Attributes of Variables

The keyword __attribute__ allows you to specify special attributes of variables or structure fields. This keyword is followed by an attribute specification inside double parentheses. Eight attributes are currently defined for variables: aligned, mode, nocommon, packed, section, transparent_union, unused, and weak. Other attributes are available for functions (see section Declaring Attributes of Functions) and for types (see section Specifying Attributes of Types).

You may also specify attributes with `__' preceding and following each keyword. This allows you to use them in header files without being concerned about a possible macro of the same name. For example, you may use __aligned__ instead of aligned.

aligned (alignment)
This attribute specifies a minimum alignment for the variable or structure field, measured in bytes. For example, the declaration:
int x __attribute__ ((aligned (16))) = 0;
causes the compiler to allocate the global variable x on a 16-byte boundary. On a 68040, this could be used in conjunction with an asm expression to access the move16 instruction which requires 16-byte aligned operands. You can also specify the alignment of structure fields. For example, to create a double-word aligned int pair, you could write:
struct foo { int x[2] __attribute__ ((aligned (8))); };
This is an alternative to creating a union with a double member that forces the union to be double-word aligned. It is not possible to specify the alignment of functions; the alignment of functions is determined by the machine's requirements and cannot be changed. You cannot specify alignment for a typedef name because such a name is just an alias, not a distinct type. As in the preceding examples, you can explicitly specify the alignment (in bytes) that you wish the compiler to use for a given variable or structure field. Alternatively, you can leave out the alignment factor and just ask the compiler to align a variable or field to the maximum useful alignment for the target machine you are compiling for. For example, you could write:
short array[3] __attribute__ ((aligned));
Whenever you leave out the alignment factor in an aligned attribute specification, the compiler automatically sets the alignment for the declared variable or field to the largest alignment which is ever used for any data type on the target machine you are compiling for. Doing this can often make copy operations more efficient, because the compiler can use whatever instructions copy the biggest chunks of memory when performing copies to or from the variables or fields that you have aligned this way. The aligned attribute can only increase the alignment; but you can decrease it by specifying packed as well. See below. Note that the effectiveness of aligned attributes may be limited by inherent limitations in your linker. On many systems, the linker is only able to arrange for variables to be aligned up to a certain maximum alignment. (For some linkers, the maximum supported alignment may be very very small.) If your linker is only able to align variables up to a maximum of 8 byte alignment, then specifying aligned(16) in an __attribute__ will still only provide you with 8 byte alignment. See your linker documentation for further information.
mode (mode)
This attribute specifies the data type for the declaration--whichever type corresponds to the mode mode. This in effect lets you request an integer or floating point type according to its width. You may also specify a mode of `byte' or `__byte__' to indicate the mode corresponding to a one-byte integer, `word' or `__word__' for the mode of a one-word integer, and `pointer' or `__pointer__' for the mode used to represent pointers.
This attribute specifies requests GNU CC not to place a variable "common" but instead to allocate space for it directly. If you specify the `-fno-common' flag, GNU CC will do this for all variables. Specifying the nocommon attribute for a variable provides an initialization of zeros. A variable may only be initialized in one source file.
The packed attribute specifies that a variable or structure field should have the smallest possible alignment--one byte for a variable, and one bit for a field, unless you specify a larger value with the aligned attribute. Here is a structure in which the field x is packed, so that it immediately follows a:
struct foo
  char a;
  int x[2] __attribute__ ((packed));
section ("section-name")
Normally, the compiler places the objects it generates in sections like data and bss. Sometimes, however, you need additional sections, or you need certain particular variables to appear in special sections, for example to map to special hardware. The section attribute specifies that a variable (or function) lives in a particular section. For example, this small program uses several specific section names:
struct duart a __attribute__ ((section ("DUART_A"))) = { 0 };
struct duart b __attribute__ ((section ("DUART_B"))) = { 0 };
char stack[10000] __attribute__ ((section ("STACK"))) = { 0 };
int init_data __attribute__ ((section ("INITDATA"))) = 0;

  /* Initialize stack pointer */
  init_sp (stack + sizeof (stack));

  /* Initialize initialized data */
  memcpy (&init_data, &data, &edata - &data);

  /* Turn on the serial ports */
  init_duart (&a);
  init_duart (&b);
Use the section attribute with an initialized definition of a global variable, as shown in the example. GNU CC issues a warning and otherwise ignores the section attribute in uninitialized variable declarations. You may only use the section attribute with a fully initialized global definition because of the way linkers work. The linker requires each object be defined once, with the exception that uninitialized variables tentatively go in the common (or bss) section and can be multiply "defined". You can force a variable to be initialized with the `-fno-common' flag or the nocommon attribute. Some file formats do not support arbitrary sections so the section attribute is not available on all platforms. If you need to map the entire contents of a module to a particular section, consider using the facilities of the linker instead.
This attribute, attached to a function parameter which is a union, means that the corresponding argument may have the type of any union member, but the argument is passed as if its type were that of the first union member. For more details see See section Specifying Attributes of Types. You can also use this attribute on a typedef for a union data type; then it applies to all function parameters with that type.
This attribute, attached to a variable, means that the variable is meant to be possibly unused. GNU CC will not produce a warning for this variable.
The weak attribute is described in See section Declaring Attributes of Functions.
model (model-name)
Use this attribute on the M32R/D to set the addressability of an object. The identifier model-name is one of small, medium, or large, representing each of the code models. Small model objects live in the lower 16MB of memory (so that their addresses can be loaded with the ld24 instruction). Medium and large model objects may live anywhere in the 32 bit address space (the compiler will generate seth/add3 instructions to load their addresses).

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

[Contents]   [Back]   [Prev]   [Up]   [Next]   [Forward]