Introduction to u attribute_u keyword of gcc

Introduction to the _attribute_keyword of gcc

See:

_attribute_You can set function properties, variable properties, type properties.

1. Function Properties

_u attribute_u can add some attributes to the function declaration, allowing the compiler to help with more error checking.

  1. __attribute__(format(printf, m, n))
  • The mth parameter is a formatted string
  • The first parameter in the set of n parameters, parameter'..."The first parameter in the function is the nth in the total number of arguments,
    If it is a member function of a class, add 1 because there is a this pointer

A simple sample program.This sample program is of no use; it has only been compiled and run to prove that the syntax is correct.

// gcc -Wall test.c 

#include <stdio.h>
#include <stdlib.h>

void myprint(const char *format,...) __attribute__((format(printf,1,2)));

void myprint(const char *format,...)
{
    printf("Hello\n");
}

int main()
{
    int i = 10;
    myprint("i=%d", i);
    return 0;
}
  1. __attribute__(format(scanf, m, n))

Grammar is similar to the above, but less frequently used.

  1. __attribute__((noreturn))

This property tells the compiler that the function does not return a value.This property avoids error messages when certain caller functions need to return a value but cannot run to the return value and have already exited.This is the way abort() and exit() are declared in C library functions, as follows:

extern void exit(int)   __attribute__((noreturn));
extern void abort(void) __attribute__((noreturn));

Sample program:

#include <stdio.h>
#include <stdlib.h>

void myexit(int n) __attribute__((noreturn));

void myexit(int n)
{
    printf("I will exit with %d\n", n);
    exit(n);
}

int main()
{
    int i = -1;
    if (i<0) {
        myexit(i);
    }
    else {
        myexit(0);
    }
    printf("Will never hit here\n");
    
    return 0;
}
  1. __attribute__((const))

The purpose of this property is to allow the compiler to optimize by returning only the first result, in addition to the first operation required.
This property applies primarily to nonstatic functions, and the return value depends only on the input parameters.

Sample program:

#include <stdio.h>
#include <stdlib.h>

int mycalc(int n) __attribute__((const));
int mycalc2() __attribute__((const));  // not a good example but can pass building

int mycalc(int n)
{
    if (n<-100 || n>100) return 0;
    return n*n;
}

int mycalc2()
{
    return 10;
}

int main()
{
    int i;
    for(i=0; i<10; i++)
    {
        printf("result = %d\n", mycalc(8));
        printf("result = %d\n", mycalc2());
    }
    
    return 0;
}
  1. Use multiple attributes simultaneously

It is also common to use multiple u attribute s_u in the same function declaration.
You can choose several separate u attribute s_u or write them together as an example:

// Pass the print information to stderr and exit
extern void die(const char *format, ...)
     __attribute__((noreturn))
     __attribute__((format(printf, 1, 2)));

// OR
extern void die(const char *format, ...)
     __attribute__((noreturn, format(printf, 1, 2)));

2. Variable Attributes

  1. __attribute__(aligned())

This property specifies the minimum alignment format for variable or structure members in bytes.For example:

int x __attribute__ ((aligned (16))) = 0;

The compiler will assign a variable in 16-byte alignment.
You can also set this property on struct member variables, for example, by creating a double-word-aligned int pair:

struct foo { int x[2] __attribute__ ((aligned (8))); };

If aligned is not followed by a specified numeric value, the compiler will use the most beneficial alignment according to the target machine.For example:

short array[3] __attribute__ ((aligned));

Selecting the maximum alignment for the target machine can improve the efficiency of the copy operation.
The aligned attribute makes the set object take up more space, whereas using packed reduces the space used by the object.
It is important to note that if the connector supports only 16-byte alignment at most, it is not helpful to define 32-byte alignment at this time.

Sample program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int x __attribute__ ((aligned (16))) = 0;
    int y __attribute__ ((aligned (128))) = 0;

    // Not every int element is 8 bytes aligned,
    // Instead, two int elements are aligned by exactly one 8-byte, and three int elements open up the second 8-byte
    struct foo { int x[2] __attribute__ ((aligned (8))); };
    struct foo sf; 
    struct foo3 { int x[3] __attribute__ ((aligned (8))); };
    struct foo4 { int x[4] __attribute__ ((aligned (8))); };
    struct foo5 { int x[5] __attribute__ ((aligned (8))); };

    short array2[2] __attribute__ ((aligned));
    short array3[3] __attribute__ ((aligned));
    short array4[4] __attribute__ ((aligned));
    
    printf("sizeof(x) = %d\n", sizeof(x));      // 4
    printf("sizeof(y) = %d\n", sizeof(y));      // 4
    printf("sizeof(foo) = %d\n", sizeof(struct foo));     // 8
    printf("sizeof(foo.x) = %d\n", sizeof(sf.x));         // 8
    printf("sizeof(foo3) = %d\n", sizeof(struct foo3));  // 16
    printf("sizeof(foo4) = %d\n", sizeof(struct foo4));  // 16
    printf("sizeof(foo5) = %d\n", sizeof(struct foo5));  // 24
    printf("sizeof(short) = %d\n", sizeof(short));    // 2
    printf("sizeof(array2) = %d\n", sizeof(array2));  // 4
    printf("sizeof(array3) = %d\n", sizeof(array3));  // 6
    printf("sizeof(array4) = %d\n", sizeof(array4));  // 8
    
    return 0;
}
  1. __attribute__((packed))

This property allows variables or structure members to use the least alignment, that is, to align variables in bytes and to align field s in bits.

struct mypack   // size is 9=1+4+4
{
  char a;
  int x[2] __attribute__ ((packed));
};
  1. Other attribute values: (see the reference at the beginning of the article for details)
  • cleanup
  • common
  • nocommon
  • deprecated
  • mode
  • section
  • shared
  • tls_model
  • transparent_union
  • unused
  • vector_size
  • weak
  • dllimport
  • dlexport

3. Type Attributes

The keyword u attribute_ can also set properties for struct s or union s.
There are roughly six parameter values that can be set:

  • aligned
  • packed
  • transparent_union
  • unused
  • deprecated
  • may_alias
  1. __attribute__((aligned(alignment)))

This property sets an alignment format (in bytes) of a specified size, for example:

struct S1 { short f[3]; } __attribute__ ((aligned (8)));
typedef int more_aligned_int __attribute__ ((aligned (8)));

This declaration will force the compiler to ensure that variables of type struct S or more-aligned-int are 8-byte aligned when allocating space.
Similarly, you can use the default alignment.If aligned is not followed by any numeric values, the compiler will use the most beneficial alignment based on the target machine.For example:

struct S2 { short f[3]; } __attribute__ ((aligned));

Sample program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct S1 { short f[3]; } __attribute__ ((aligned (8)));
    struct S2 { short f[3]; } __attribute__ ((aligned));
    typedef int more_aligned_int __attribute__ ((aligned (8)));

    int array[3];
    // more_aligned_int array[1]; // compilation error: alignment of array elements is greater than element size

    printf("sizeof(S1)=%d\n", sizeof(struct S1));    // 8
    printf("sizeof(S2)=%d\n", sizeof(struct S2));    // 16
    printf("sizeof(more_aligned_int)=%d\n", sizeof(more_aligned_int)); // 4
    printf("sizeof(array)=%d\n", sizeof(array));     // 12
    printf("sizeof(long)=%d\n", sizeof(long));       // 8

    return 0;
}
  1. __attribute__((packed))

Use this property to define a struct or union type and set the memory constraints for each variable of its type.

In the example below, values in my-packed-struct type variable arrays will be held tightly together, but internal member variables s will not be "packed".
If you want internal member variables to also be packed, my_unpacked_struct also needs to use packed for the appropriate constraints.

Sample program:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    struct my_unpacked_struct   // size is 8=4+4
    {
        char c;
        int i;
    };
     
    struct my_packed_struct  // size is 13=1+4+8
    {
      char c;
      int i;
      struct my_unpacked_struct s;
    }__attribute__ ((__packed__));
    
    struct my_packed_struct2    // size is 5=1+4
    {
      char c;
      int i;
    }__attribute__ ((__packed__));
    
    printf("sizeof(my_unpacked_struct)=%d\n", sizeof(struct my_unpacked_struct));
    printf("sizeof(my_packed_struct)=%d\n", sizeof(struct my_packed_struct));
    printf("sizeof(my_packed_struct2)=%d\n", sizeof(struct my_packed_struct2));

    return 0;
}

These are just a few common uses.For more usage, refer to the three references at the beginning of the article.

(finished)

172 original articles published, 337 awarded, 490,000 visits+
His message board follow

Tags: Attribute less

Posted on Fri, 31 Jan 2020 22:02:43 -0500 by luuno