GNU C __attribute__ mechanism

GNU C __attribute__ mechanism

Syntax format of attribute

attribute ((attribute-list))

Attribute is preceded and followed by two underscores, followed by two pairs of meta-brackets. attribute-list is a comma-separated list of attributes. attribute ((attribute-list)) is placed before the “;” at the end of the declaration.

Common properties

packed

Let the compiler cancel the byte optimization alignment of the structure during compilation and align it according to the actual number of bytes occupied.

  • pack can compress the memory space occupied by variables.
  • pack acts on the definition of a structure or class.
  • The function of pack is to change the layout rules of member variables in a structure or class.
  • If the default pack of a certain structure is n and the alignment rule m specified by pack is greater than n, the pack is ignored.
  • pack must be the nth power of 2 when specifying rules.

For example, two structures are defined in the source code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
struct unpacked_str
{
  uint8_t x;
  uint16_t y;
};

struct packed_str
{
  uint8_t x;
  uint16_t y;
}__attribute__ ((packed));

struct unpacked_str strupkd;
struct packed_str strpkd;

int main(void)
{
  printf("%d", sizeof(strupkd));
  printf("%d", sizeof(strpkd));
}

Compiled using clang, the outputs are 4 and 3 respectively when running.

aligned

Specifies the minimum alignment format of variables or structure members, in bytes. Let the user decide how many bytes to align the variable.

1
2
3
4
aligned既可以作用于结构体或类的定义,也可以作用于变量的声明。
aligned只是建议编译器对指定变量或指定类型的变量分配内存时的规则。
若某一个结构体的默认pack为n,若aligned指定的对齐规则s大于n,则此时结构体的大小一定为s的整数倍。
aligned指定规则时都必须为2的n次幂。
  • When aligned is applied to a variable, its function is to tell the compiler that when allocating memory for the variable, it should be allocated in the memory specified for it. Acting on the variable will not change the size of the variable.

A 32-bit variable is defined in the code:

1
uint32_t var_in_8bytes __attribute__((aligned(8)));

The memory starting address of the variable var_in_8bytes is a multiple of 8.

  • When aligned acts on a type, its role is to tell the compiler that all variables declared in the type must be allocated in memory with the specified alignment. When this attribute is applied to a structure declaration, it may change the size of the structure.
1
2
3
4
5
6
7
8
struct Test{
  char a[3];
} __attribute__((aligned(8)));

int main() {
  //8
  std::cout << sizeof(Test);
}

As shown above, when align is applied to a structure definition, it will change the size of the structure. The final size of the structure is an integer multiple of the size specified by aligned.

section

section controls the section name of a variable or function at compile time. It is widely used in embedded software development. For example, when there is external Flash or RAM, variables or functions need to be placed in the external storage space. You can specify the segment name in the link script to operate. When programming an MCU using MPU (memory protection), it is necessary to divide the memory into areas and place variables or codes into the corresponding areas. This is usually achieved through segment operations.

1
2
const int identifier[3] __attribute__ ((section ("ident"))) = { 1,2,3 };
void myfunction (void) __attribute__ ((section ("ext_function")))

After the above code is compiled, the sections where the array and function are located are “indent” and “ext_function” respectively.

unused

It means that the function or variable is likely to be unused, and the compiler will not generate a warning for this function. It can be declared on parameters that are not used in the function implementation, for example:

1
int main(int argc __attribute__((unused)), char **argv)

used

This attribute is attached to a variable that has static storage, meaning that the variable must be retained even if it does not appear to be referenced. Otherwise, when linking, the linker finds that a variable is not referenced and will optimize the variable.

weak

If two or more global symbols have the same name and one of them is declared as a weak symbol, these global symbols will not cause a redefinition error. When ordinary symbols exist, the linker ignores weak symbols. If ordinary symbols do not exist, weak symbols are used. Functions such as overloading and callbacks can be implemented.

记录并分享
Built with Hugo
Theme Stack designed by Jimmy