이 기사는 C 언어-CSDN 블로그___attribute__에서 __attribute__를 사용하여 _qlexcel의 열을 재인쇄합니다.
C 언어에서 __attribute__의 사용법을 기록하는 데 사용됩니다.
1. 소개
GNU C의 주요 기능은 __attribute__ 메커니즘입니다. __attribute__는 함수 속성( Function Attribute), 변수 속성(Variable Attribute) 및 유형 속성(Type Attribute)을 설정할 수 있습니다 .
__attribute__의 쓰기 기능은 다음과 같습니다. __attribute__ 앞뒤에 두 개의 밑줄이 있고 그 뒤에 원래 대괄호 쌍이 있으며 해당 __attribute__ 매개변수가 대괄호 안에 있습니다.
__attribute__ 구문 형식: __attribute__ ((attribute-list))
__attribute__ 키워드는 구조(struct) 또는 공용체(union)에 대한 속성을 설정할 수도 있습니다. 약 6개의 매개변수 값을 설정할 수 있습니다.
__attribute__ 매개변수를 사용할 때 매개변수 앞뒤에 "__"(밑줄 2개)를 추가할 수도 있습니다. 헤더 파일에 같은 이름의 매크로 정의가 있습니다.
2. __attribute__의 매개변수 소개
1, 정렬
다음과 같이 개체의 정렬 형식(바이트)을 지정합니다.
struct S {
short b[3];
} __attribute__ ((aligned (8)));
typedef int int32_t __attribute__ ((aligned (8)));
이 선언은 컴파일러가 struct S 또는 int32_t 유형의 변수가 8바이트 정렬로 할당되도록 보장하도록 합니다.
위에서 언급했듯이 정렬 형식을 수동으로 지정할 수 있으며 마찬가지로 기본 정렬을 사용할 수 있습니다. 정렬 바로 뒤에 지정된 숫자 값이 오지 않으면 컴파일러는 대상 시스템에 대해 가장 크고 가장 유익한 정렬을 사용합니다. 예를 들어:
struct S {
short b[3];
} __attribute__ ((aligned));
여기서 sizeof(short)의 크기가 2byte라면 S의 크기는 6이다. 2의 거듭제곱 값을 취하여 값이 6보다 크거나 같으면 값이 8이므로 컴파일러는 S 유형 의 정렬을 8바이트로 설정합니다.
얼라인드 속성은 설정되는 객체가 더 많은 공간을 차지하도록 하는 반면, 패킹을 사용하면 객체가 차지하는 공간을 줄일 수 있습니다.
속성 속성의 효율성은 링커와도 관련이 있다는 점에 유의해야 합니다.링커가 최대 16바이트 정렬만 지원하는 경우 이 시점에서 32바이트 정렬을 정의하는 것은 쓸모가 없습니다.
2, 포장
이 특성을 사용하여 구조체 또는 공용체 유형을 정의하고 해당 유형의 각 변수에 대한 메모리 제약 조건을 설정합니다. 컴파일러에게 컴파일 과정에서 구조의 최적화된 정렬(1바이트 정렬 사용)을 취소하고 실제 차지하는 바이트 수에 따라 정렬하도록 지시하는 것인데, 이는 GCC 고유의 구문입니다. 이 함수는 운영 체제와 관련이 없으며 컴파일러와 관련이 있습니다.gcc 컴파일러는 컴팩트 모드가 아닙니다.저는 Windows에 있으며 vc 컴파일러는 컴팩트하지 않지만 tc 컴파일러는 컴팩트합니다.
다음 예에서, packed_struct 유형의 변수 배열에 있는 값은 서로 근접하지만 내부 멤버 변수 s는 "팩"되지 않습니다. 내부 멤버 변수를 패킹하려면 unpacked-struct도 "팩"됩니다. Packed는 해당 제약 조건에 사용해야 합니다.
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、에서
절대 위치 지정, Flash에서 변수 또는 함수를 절대적으로 찾거나 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, 섹션
섹션에 관해서는 RO RI ZI라고 해야 합니다. ARM 컴파일러가 컴파일된 후 코드는 여러 섹션으로 나뉩니다. RO 섹션(ReadOnly)은 코드 섹션과 상수를 저장하고 RW 섹션(ReadWrite)은 읽고 쓸 수 있는 정적을 저장합니다. 변수 및 전역 변수 ZI 섹션(ZeroInit)은 0으로 초기화된 RW 세그먼트에 저장되는 변수입니다.
따라서 이 문서의 일반적인 의미는 명확합니다. __attribute__((section("section_name"))), 함수 또는 함수의 데이터를 지정된 이름 "section_name"에 해당하는 섹션에 넣는 것입니다.
1) 컴파일 타임에 변수의 세그먼트를 지정합니다.
__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) 컴파일 타임에 함수의 세그먼트 지정
__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. 복수속성, 겸용
u8 FileAddr[100] __attribute__ ((section ("FILE_RAM"), zero_init,aligned(4)));