gcc: Common Type Attributes

1 
1 6.33.1 Common Type Attributes
1 -----------------------------
1 
1 The following type attributes are supported on most targets.
1 
1 'aligned (ALIGNMENT)'
1      This attribute specifies a minimum alignment (in bytes) for
1      variables of the specified type.  For example, the declarations:
1 
1           struct S { short f[3]; } __attribute__ ((aligned (8)));
1           typedef int more_aligned_int __attribute__ ((aligned (8)));
1 
1      force the compiler to ensure (as far as it can) that each variable
1      whose type is 'struct S' or 'more_aligned_int' is allocated and
1      aligned _at least_ on a 8-byte boundary.  On a SPARC, having all
1      variables of type 'struct S' aligned to 8-byte boundaries allows
1      the compiler to use the 'ldd' and 'std' (doubleword load and store)
1      instructions when copying one variable of type 'struct S' to
1      another, thus improving run-time efficiency.
1 
1      Note that the alignment of any given 'struct' or 'union' type is
1      required by the ISO C standard to be at least a perfect multiple of
1      the lowest common multiple of the alignments of all of the members
1      of the 'struct' or 'union' in question.  This means that you _can_
1      effectively adjust the alignment of a 'struct' or 'union' type by
1      attaching an 'aligned' attribute to any one of the members of such
1      a type, but the notation illustrated in the example above is a more
1      obvious, intuitive, and readable way to request the compiler to
1      adjust the alignment of an entire 'struct' or 'union' type.
1 
1      As in the preceding example, you can explicitly specify the
1      alignment (in bytes) that you wish the compiler to use for a given
1      'struct' or 'union' type.  Alternatively, you can leave out the
1      alignment factor and just ask the compiler to align a type to the
1      maximum useful alignment for the target machine you are compiling
1      for.  For example, you could write:
1 
1           struct S { short f[3]; } __attribute__ ((aligned));
1 
1      Whenever you leave out the alignment factor in an 'aligned'
1      attribute specification, the compiler automatically sets the
1      alignment for the type to the largest alignment that is ever used
1      for any data type on the target machine you are compiling for.
1      Doing this can often make copy operations more efficient, because
1      the compiler can use whatever instructions copy the biggest chunks
1      of memory when performing copies to or from the variables that have
1      types that you have aligned this way.
1 
1      In the example above, if the size of each 'short' is 2 bytes, then
1      the size of the entire 'struct S' type is 6 bytes.  The smallest
1      power of two that is greater than or equal to that is 8, so the
1      compiler sets the alignment for the entire 'struct S' type to 8
1      bytes.
1 
1      Note that although you can ask the compiler to select a
1      time-efficient alignment for a given type and then declare only
1      individual stand-alone objects of that type, the compiler's ability
1      to select a time-efficient alignment is primarily useful only when
1      you plan to create arrays of variables having the relevant
1      (efficiently aligned) type.  If you declare or use arrays of
1      variables of an efficiently-aligned type, then it is likely that
1      your program also does pointer arithmetic (or subscripting, which
1      amounts to the same thing) on pointers to the relevant type, and
1      the code that the compiler generates for these pointer arithmetic
1      operations is often more efficient for efficiently-aligned types
1      than for other types.
1 
1      Note that the effectiveness of 'aligned' attributes may be limited
1      by inherent limitations in your linker.  On many systems, the
1      linker is only able to arrange for variables to be aligned up to a
1      certain maximum alignment.  (For some linkers, the maximum
1      supported alignment may be very very small.)  If your linker is
1      only able to align variables up to a maximum of 8-byte alignment,
1      then specifying 'aligned(16)' in an '__attribute__' still only
1      provides you with 8-byte alignment.  See your linker documentation
1      for further information.
1 
1      The 'aligned' attribute can only increase alignment.  Alignment can
1      be decreased by specifying the 'packed' attribute.  See below.
1 
1 'warn_if_not_aligned (ALIGNMENT)'
1      This attribute specifies a threshold for the structure field,
1      measured in bytes.  If the structure field is aligned below the
1      threshold, a warning will be issued.  For example, the declaration:
1 
1           typedef unsigned long long __u64
1              __attribute__((aligned(4),warn_if_not_aligned(8)));
1 
1           struct foo
1           {
1             int i1;
1             int i2;
1             __u64 x;
1           };
1 
1      causes the compiler to issue an warning on 'struct foo', like
1      'warning: alignment 4 of 'struct foo' is less than 8'.  It is used
1      to define 'struct foo' in such a way that 'struct foo' has the same
1      layout and the structure field 'x' has the same alignment when
1      '__u64' is aligned at either 4 or 8 bytes.  Align 'struct foo' to 8
1      bytes:
1 
1           struct foo
1           {
1             int i1;
1             int i2;
1             __u64 x;
1           } __attribute__((aligned(8)));
1 
1      silences the warning.  The compiler also issues a warning, like
1      'warning: 'x' offset 12 in 'struct foo' isn't aligned to 8', when
1      the structure field has the misaligned offset:
1 
1           struct foo
1           {
1             int i1;
1             int i2;
1             int i3;
1             __u64 x;
1           } __attribute__((aligned(8)));
1 
1      This warning can be disabled by '-Wno-if-not-aligned'.
1 
1 'bnd_variable_size'
1      When applied to a structure field, this attribute tells Pointer
1      Bounds Checker that the size of this field should not be computed
1      using static type information.  It may be used to mark
1      variably-sized static array fields placed at the end of a
1      structure.
1 
1           struct S
1           {
1             int size;
1             char data[1];
1           }
1           S *p = (S *)malloc (sizeof(S) + 100);
1           p->data[10] = 0; //Bounds violation
1 
1      By using an attribute for the field we may avoid unwanted bound
1      violation checks:
1 
1           struct S
1           {
1             int size;
1             char data[1] __attribute__((bnd_variable_size));
1           }
1           S *p = (S *)malloc (sizeof(S) + 100);
1           p->data[10] = 0; //OK
1 
1 'deprecated'
1 'deprecated (MSG)'
1      The 'deprecated' attribute results in a warning if the type is used
1      anywhere in the source file.  This is useful when identifying types
1      that are expected to be removed in a future version of a program.
1      If possible, the warning also includes the location of the
1      declaration of the deprecated type, to enable users to easily find
1      further information about why the type is deprecated, or what they
1      should do instead.  Note that the warnings only occur for uses and
1      then only if the type is being applied to an identifier that itself
1      is not being declared as deprecated.
1 
1           typedef int T1 __attribute__ ((deprecated));
1           T1 x;
1           typedef T1 T2;
1           T2 y;
1           typedef T1 T3 __attribute__ ((deprecated));
1           T3 z __attribute__ ((deprecated));
1 
1      results in a warning on line 2 and 3 but not lines 4, 5, or 6.  No
1      warning is issued for line 4 because T2 is not explicitly
1      deprecated.  Line 5 has no warning because T3 is explicitly
1      deprecated.  Similarly for line 6.  The optional MSG argument,
1      which must be a string, is printed in the warning if present.
1 
1      The 'deprecated' attribute can also be used for functions and
DONTPRINTYET 1      variables (⇒Function Attributes, *noteVariable
1DONTPRINTYET 1      variables (⇒Function Attributes, ⇒Variable

      Attributes.)
1 
1 'designated_init'
1      This attribute may only be applied to structure types.  It
1      indicates that any initialization of an object of this type must
1      use designated initializers rather than positional initializers.
1      The intent of this attribute is to allow the programmer to indicate
1      that a structure's layout may change, and that therefore relying on
1      positional initialization will result in future breakage.
1 
1      GCC emits warnings based on this attribute by default; use
1      '-Wno-designated-init' to suppress them.
1 
1 'may_alias'
1      Accesses through pointers to types with this attribute are not
1      subject to type-based alias analysis, but are instead assumed to be
1      able to alias any other type of objects.  In the context of section
1      6.5 paragraph 7 of the C99 standard, an lvalue expression
1      dereferencing such a pointer is treated like having a character
1      type.  See '-fstrict-aliasing' for more information on aliasing
1      issues.  This extension exists to support some vector APIs, in
1      which pointers to one vector type are permitted to alias pointers
1      to a different vector type.
1 
1      Note that an object of a type with this attribute does not have any
1      special semantics.
1 
1      Example of use:
1 
1           typedef short __attribute__((__may_alias__)) short_a;
1 
1           int
1           main (void)
1           {
1             int a = 0x12345678;
1             short_a *b = (short_a *) &a;
1 
1             b[1] = 0;
1 
1             if (a == 0x12345678)
1               abort();
1 
1             exit(0);
1           }
1 
1      If you replaced 'short_a' with 'short' in the variable declaration,
1      the above program would abort when compiled with
1      '-fstrict-aliasing', which is on by default at '-O2' or above.
1 
1 'packed'
1      This attribute, attached to 'struct' or 'union' type definition,
1      specifies that each member (other than zero-width bit-fields) of
1      the structure or union is placed to minimize the memory required.
1      When attached to an 'enum' definition, it indicates that the
1      smallest integral type should be used.
1 
1      Specifying the 'packed' attribute for 'struct' and 'union' types is
1      equivalent to specifying the 'packed' attribute on each of the
1      structure or union members.  Specifying the '-fshort-enums' flag on
1      the command line is equivalent to specifying the 'packed' attribute
1      on all 'enum' definitions.
1 
1      In the following example 'struct my_packed_struct''s members are
1      packed closely together, but the internal layout of its 's' member
1      is not packed--to do that, 'struct my_unpacked_struct' needs to be
1      packed too.
1 
1           struct my_unpacked_struct
1            {
1               char c;
1               int i;
1            };
1 
1           struct __attribute__ ((__packed__)) my_packed_struct
1             {
1                char c;
1                int  i;
1                struct my_unpacked_struct s;
1             };
1 
1      You may only specify the 'packed' attribute attribute on the
1      definition of an 'enum', 'struct' or 'union', not on a 'typedef'
1      that does not also define the enumerated type, structure or union.
1 
1 'scalar_storage_order ("ENDIANNESS")'
1      When attached to a 'union' or a 'struct', this attribute sets the
1      storage order, aka endianness, of the scalar fields of the type, as
1      well as the array fields whose component is scalar.  The supported
1      endiannesses are 'big-endian' and 'little-endian'.  The attribute
1      has no effects on fields which are themselves a 'union', a 'struct'
1      or an array whose component is a 'union' or a 'struct', and it is
1      possible for these fields to have a different scalar storage order
1      than the enclosing type.
1 
1      This attribute is supported only for targets that use a uniform
1      default scalar storage order (fortunately, most of them), i.e.
1      targets that store the scalars either all in big-endian or all in
1      little-endian.
1 
1      Additional restrictions are enforced for types with the reverse
1      scalar storage order with regard to the scalar storage order of the
1      target:
1 
1         * Taking the address of a scalar field of a 'union' or a
1           'struct' with reverse scalar storage order is not permitted
1           and yields an error.
1         * Taking the address of an array field, whose component is
1           scalar, of a 'union' or a 'struct' with reverse scalar storage
1           order is permitted but yields a warning, unless
1           '-Wno-scalar-storage-order' is specified.
1         * Taking the address of a 'union' or a 'struct' with reverse
1           scalar storage order is permitted.
1 
1      These restrictions exist because the storage order attribute is
1      lost when the address of a scalar or the address of an array with
1      scalar component is taken, so storing indirectly through this
1      address generally does not work.  The second case is nevertheless
1      allowed to be able to perform a block copy from or to the array.
1 
1      Moreover, the use of type punning or aliasing to toggle the storage
1      order is not supported; that is to say, a given scalar object
1      cannot be accessed through distinct types that assign a different
1      storage order to it.
1 
1 'transparent_union'
1 
1      This attribute, attached to a 'union' type definition, indicates
1      that any function parameter having that union type causes calls to
1      that function to be treated in a special way.
1 
1      First, the argument corresponding to a transparent union type can
1      be of any type in the union; no cast is required.  Also, if the
1      union contains a pointer type, the corresponding argument can be a
1      null pointer constant or a void pointer expression; and if the
1      union contains a void pointer type, the corresponding argument can
1      be any pointer expression.  If the union member type is a pointer,
1      qualifiers like 'const' on the referenced type must be respected,
1      just as with normal pointer conversions.
1 
1      Second, the argument is passed to the function using the calling
1      conventions of the first member of the transparent union, not the
1      calling conventions of the union itself.  All members of the union
1      must have the same machine representation; this is necessary for
1      this argument passing to work properly.
1 
1      Transparent unions are designed for library functions that have
1      multiple interfaces for compatibility reasons.  For example,
1      suppose the 'wait' function must accept either a value of type 'int
1      *' to comply with POSIX, or a value of type 'union wait *' to
1      comply with the 4.1BSD interface.  If 'wait''s parameter were 'void
1      *', 'wait' would accept both kinds of arguments, but it would also
1      accept any other pointer type and this would make argument type
1      checking less useful.  Instead, '<sys/wait.h>' might define the
1      interface as follows:
1 
1           typedef union __attribute__ ((__transparent_union__))
1             {
1               int *__ip;
1               union wait *__up;
1             } wait_status_ptr_t;
1 
1           pid_t wait (wait_status_ptr_t);
1 
1      This interface allows either 'int *' or 'union wait *' arguments to
1      be passed, using the 'int *' calling convention.  The program can
1      call 'wait' with arguments of either type:
1 
1           int w1 () { int w; return wait (&w); }
1           int w2 () { union wait w; return wait (&w); }
1 
1      With this interface, 'wait''s implementation might look like this:
1 
1           pid_t wait (wait_status_ptr_t p)
1           {
1             return waitpid (-1, p.__ip, 0);
1           }
1 
1 'unused'
1      When attached to a type (including a 'union' or a 'struct'), this
1      attribute means that variables of that type are meant to appear
1      possibly unused.  GCC does not produce a warning for any variables
1      of that type, even if the variable appears to do nothing.  This is
1      often the case with lock or thread classes, which are usually
1      defined and then not referenced, but contain constructors and
1      destructors that have nontrivial bookkeeping functions.
1 
1 'visibility'
1      In C++, attribute visibility (⇒Function Attributes) can also
1      be applied to class, struct, union and enum types.  Unlike other
1      type attributes, the attribute must appear between the initial
1      keyword and the name of the type; it cannot appear after the body
1      of the type.
1 
1      Note that the type visibility is applied to vague linkage entities
1      associated with the class (vtable, typeinfo node, etc.).  In
1      particular, if a class is thrown as an exception in one shared
1      object and caught in another, the class must have default
1      visibility.  Otherwise the two shared objects are unable to use the
1      same typeinfo node and exception handling will break.
1 
1  To specify multiple attributes, separate them by commas within the
1 double parentheses: for example, '__attribute__ ((aligned (16),
1 packed))'.
1