The use of __attribute__ in C language

This article reprints  the column of _qlexcel using __attribute__ in C language-CSDN blog___attribute__

It is used to record the usage of __attribute__ in C language.

1. Introduction

A major feature of GNU C is the __attribute__ mechanism. __attribute__ can set function attributes ( Function Attribute), variable attributes (Variable Attribute) and type attributes (Type Attribute).

The writing feature of __attribute__ is: there are two underscores before and after __attribute__, followed by a pair of original brackets, and the corresponding __attribute__ parameters are inside the brackets.

__attribute__ syntax format is: __attribute__ ((attribute-list))

The keyword __attribute__ can also set attributes for a structure (struct) or union (union). Roughly six parameter values ​​can be set, namely: aligned, packed, transparent_union, unused, deprecated and may_alias.

When using the __attribute__ parameter, you can also add "__" (two underscores) before and after the parameter, for example, use __aligned__ instead of aligned, so that you can use it in the corresponding header file instead of Don't care whether there are macro definitions with the same name in the header file.

2. Parameter introduction of __attribute__

1、aligned 

Specify the alignment format of the object (in bytes), such as:

struct S {
 
short b[3];
 
} __attribute__ ((aligned (8)));
 
 
typedef int int32_t __attribute__ ((aligned (8)));

This declaration will force the compiler to ensure (to the best of its ability) that variables of type struct S or int32_t are allocated with 8-byte alignment.

As mentioned above, you can manually specify the alignment format, and likewise, you can use the default alignment. If aligned is not immediately followed by a specified numeric value, the compiler will use the largest and most beneficial alignment for your target machine. For example:

struct S {
 
short b[3];
 
} __attribute__ ((aligned));

Here, if the size of sizeof (short) is 2byte, then the size of S is 6. Take a power of 2 value so that the value is greater than or equal to 6, then the value is 8, so the compiler will set the  alignment of the S type to 8 bytes.

The aligned attribute makes the object being set occupy more space, on the contrary, using packed can reduce the space occupied by the object.

It should be noted that the effectiveness of the attribute attribute is also related to your linker. If your linker only supports a maximum of 16-byte alignment, then it is useless for you to define 32-byte alignment at this time.

2、packed

        Use this attribute to define the struct or union type, and set the memory constraint of each variable of its type. It is to tell the compiler to cancel the optimized alignment of the structure during compilation (using 1-byte alignment), and to align it according to the actual number of bytes occupied, which is a unique syntax of GCC. This function has nothing to do with the operating system, it has to do with the compiler. The gcc compiler is not in compact mode. I am in windows, and the vc compiler is not compact, but the tc compiler is compact.

        In the following example, the values ​​in the variable array of packed_struct type will be close together, but the internal member variable s will not be "packed". If you want the internal member variable to be packed, unpacked-struct will also Packed needs to be used for corresponding constraints.

    struct unpacked_struct
    {
          char c;
          int i;
    };
             
    struct packed_struct
    {
         char c;
         int  i;
         struct unpacked_struct s;
    }__attribute__ ((__packed__));

如:

    在TC下:struct my{ char ch; int a;}      sizeof(int)=2;sizeof(my)=3;(紧凑模式)
     
    在GCC下:struct my{ char ch; int a;}     sizeof(int)=4;sizeof(my)=8;(非紧凑模式)
     
    在GCC下:struct my{ char ch; int a;}__attrubte__ ((packed))        sizeof(int)=4;sizeof(my)=5
下面的例子中使用__attribute__ 属性定义了一些结构体及其变量,并给出了输出结果和对结果的分析。代码为:

    struct p
    {
        int a;
        char b;
        short c;
     
    }__attribute__((aligned(4))) pp;
     
    struct m
    {
        char a;
        int b;
        short c;
    }__attribute__((aligned(4))) mm;
     
    struct o
    {
        int a;
        char b;
        short c;
    }oo;
     
    struct x
    {
        int a;
        char b;
        struct p px;
        short c;
    }__attribute__((aligned(8))) xx;
     
    int main()
    {           
        printf("sizeof(int)=%d,sizeof(short)=%d.sizeof(char)=%d\n",sizeof(int)
                                                    ,sizeof(short),sizeof(char));
        printf("pp=%d,mm=%d \n", sizeof(pp),sizeof(mm));
        printf("oo=%d,xx=%d \n", sizeof(oo),sizeof(xx));
        return 0;
    }

输出结果:

sizeof(int)=4,sizeof(short)=2.sizeof(char)=1

pp=8,mm=12

oo=8,xx=24

分析:都是字节对齐的原理

3、at

Absolute positioning, you can absolutely locate variables or functions in Flash, or locate them in RAM.

1)、定位到flash中,一般用于固化的信息,如出厂设置的参数,上位机配置的参数,ID卡的ID号,flash标记等等

    const u16 gFlashDefValue[512] __attribute__((at(0x0800F000))) = {0x1111,0x1111,0x1111,0x0111,0x0111,0x0111};//定位在flash中,其他flash补充为00
    const u16 gflashdata__attribute__((at(0x0800F000))) = 0xFFFF;

 

2)、定位到RAM中,一般用于数据量比较大的缓存,如串口的接收缓存,再就是某个位置的特定变量

u8 USART2_RX_BUF[USART2_REC_LEN] __attribute__ ((at(0X20001000)));//接收缓冲,最大USART_REC_LEN个字节,起始地址为0X20001000.


注意:

1)、绝对定位不能在函数中定义,局部变量是定义在栈区的,栈区由MDK自动分配、释放,不能定义为绝对地址,只能放在函数外定义。

2)、定义的长度不能超过栈或Flash的大小,否则,造成栈、Flash溢出。

4、section

        When it comes to section, you have to say RO RI ZI. After the ARM compiler compiles, the code is divided into different sections. RO Section (ReadOnly) stores code sections and constants, and RW Section (ReadWrite) stores readable and writable static Variables and global variables, ZI Section (ZeroInit) is a variable stored in the RW segment initialized to 0.
        So the general meaning of this article is clear, __attribute__((section("section_name"))), its function is to put the function or data of the function into the section corresponding to the specified name "section_name".

1), specify the segment for the variable at compile time:

__attribute__((section("name")))
RealView Compilation Tools for µVision Compiler Reference Guide Version 4.0 
 
Home > Compiler-specific Features > Variable attributes > __attribute__((section("name"))) 
 
4.5.6. __attribute__((section("name")))
Normally, the ARM compiler places the objects it generates in sections like data and bss. However, you might require additional data sections or you might want a variable to appear in a special section, for example, to map to special hardware. The section attribute specifies that a variable must be placed in a particular data section. If you use the section attribute, read-only variables are placed in RO data sections, read-write variables are placed in RW data sections unless you use the zero_init attribute. In this case, the variable is placed in a ZI section.
 
Note
This variable attribute is a GNU compiler extension supported by the ARM compiler.
 
Example
/* in RO section */
const int descriptor[3] __attribute__ ((section ("descr"))) = { 1,2,3 };
/* in RW section */
long long rw[10] __attribute__ ((section ("RW")));
/* in ZI section *
long long altstack[10] __attribute__ ((section ("STACK"), zero_init));/

2) Specify a segment for the function at compile time

__attribute__((section("name")))
RealView Compilation Tools for µVision Compiler Reference Guide Version 4.0 
 
Home > Compiler-specific Features > Function attributes > __attribute__((section("name"))) 
 
4.3.13. __attribute__((section("name")))
The section function attribute enables you to place code in different sections of the image.
 
Note
This function attribute is a GNU compiler extension that is supported by the ARM compiler.
 
Example
In the following example, Function_Attributes_section_0 is placed into the RO section new_section rather than .text.
 
void Function_Attributes_section_0 (void) __attribute__ ((section ("new_section")));
void Function_Attributes_section_0 (void)
{
    static int aStatic =0;
    aStatic++;
}
In the following example, section function attribute overrides the #pragma arm section setting.
 
#pragma arm section code="foo"
  int f2()
  {
      return 1;
  }                                  // into the 'foo' area
 
  __attribute__ ((section ("bar"))) int f3()
  {
      return 1;
  }                                  // into the 'bar' area
 
  int f4()
  {
      return 1;
  }                                  // into the 'foo' area
#pragma arm section

5. Multiple attributes, combined use

u8 FileAddr[100] __attribute__ ((section ("FILE_RAM"), zero_init,aligned(4)));    

Guess you like

Origin blog.csdn.net/qq_48709036/article/details/123130788