原文网址:https://blog.csdn.net/zhzht19861011/article/details/8645497
一. 关键字和运算符1. __align(n):指示编译器在n 字节边界上对齐变量。 对于局部变量,n 值可为 1、2、4 或 8。 对于全局变量,n 可以具有最大为 2 的 0x80000000 次幂的任何值。 __align 关键字紧靠变量名称前面放置。 注意事项: 只能进行过对齐。也就是说,可以将两个字节的对象按 4 个字节对齐,而不能将 4 个字节的对象按两个字节对齐。 用法举例:
__align(8) char buffer[128]; /* buffer从8字节对齐边界开始*/
void foo(void)
{
...
__align(16) int i; /* 这个对齐值是不允许用在局部变量中的*/
...
}
__align(16) int i; /* 作为一个全局变量,这个对齐值是被允许的*/
2. __asm:此关键字用于将信息从编译器传递到 ARM 汇编器armasm。 用法: a. 嵌入式汇编器 可以使用 __asm 关键字声明或定义嵌入式汇编函数。例如: [cpp] view plain copy
- <code class="language-csharp"> __asm void my_strcpy(const char *src, char *dst); </code>
b. 内联汇编器 可以使用 __asm 关键字将内联汇编合并到函数中。例如:
int qadd(int i, int j)
{
int res;
__asm
{
QADD res, i, j
}
return res;
}
c. 汇编器标签 可以使用 __asm 关键字为 C 符号指定汇编器标签。例如: [cpp] view plain copy
- <code class="language-csharp"> int count __asm__("count_v1"); // export count_v1, not count</code>
d. 已命名的寄存器变量 可以使用 __asm 关键字声明已命名的寄存器变量。例如: [cpp] view plain copy
- <code class="language-csharp"> register int foo __asm("r0");</code>
3.__forceinline:强制编译器内联编译C或C++ 函。
说明:
__forceinline 的语义与 C++ inline 关键字的语义完全相同。编译器尝试内联限定为 __forceinline 的函数,而不考虑其特性。但是,如果这样做导致出现问题,编译器将不内联函数。例如,递归函数仅内联到本身一次。
注:
此关键字具有等效的函数属性 __attribute__((always_inline))。
用法举例:
__forceinline static int max(int x, in y)
{
return x > y ? x : y; // always inline if possible
}
4.__inline:提示编译器在合理的情况下内联编译C或C++ 函数。 说明:
__inline 的语义与 C++ inline 关键字的语义完全相同。
用法举例:
__inline int f(int x)
{
return x*5+1;
}
int g(int x, int y)
{
return f(x) + f(y);
}
5.__packed:将所有有效类型的对齐边界设置为 1。这就意味着: 不会插入填充以对齐压缩对象 使用未对齐的访问读取或写入压缩类型的对象。
使用 __packed 限定符声明结构或联合后,__packed 将应用于该结构或联合的所有成员。成员之间或结构末尾均没有填充。必须使用__packed 声明压缩结构的所有子结构。可以单独压缩非压缩结构的整型子字段。 用法: 若要将结构映射到外部数据结构或访问未对齐数据,__packed 限定符非常有用;但由于访问开销相对较高,通常对节省数据大小并没有什么帮助。通过仅对需要压缩的结构中的字段进行压缩,可以减少未对齐访问的数量。 注: 在硬件中不支持未对齐访问的 ARM 处理器(例如,ARMv6 之前的处理器)上,访问未对齐的数据时可能会在代码大小和执行速度方面产生较高的成本。必须最大限度减少通过压缩结构进行的数据访问,以避免增加代码大小和降低性能。 用法举例1 - 压缩结构
typedef __packed struct
{
char x; // 结构体所有成员都会被__packed限定
int y;
} X; // 结构体占5字节,如果不使用__packed,这个结构占8字节
int f(X *p)
{
return p->y; // 执行一次未对齐读数据
}
typedef struct
{
short x;
char y;
__packed int z; // 仅这一个变量受到__packed约束
char a;
} Y; // 这个结构体占8字节
int g(Y *p)
{
return p->z + p->x; // 只有读区域z是未对齐的
}
用法举例2 - 指向压缩类型的指针
typedef __packed int* PpI; /* 指向一个__packed int型变量*/
__packed int *p; /* 指向一个__packed int型变量*/
PpI p2; /* 'p2' 和'p'的类型相同 */
/* __packed可看作一个限定符*/
/* 就像'const'或者'volatile'一样 */
typedef int *PI; /* 指向一个int型变量 */
__packed PI p3; /* 一个指向正常int型变量的__packed指针*/
/* -- 'p'和'p2'不是一个类型 */
int *__packed p4; /* 'p4'和'p3'的类型相同 */
|