哈喽 各位读者伙伴大家好 本篇文章讲一下C++新特性 alignas&alignof
在这之前 我们大家应该先了解一下数据对齐的问题
什么是数据对齐问题呢?
以下是两个结构体在内存中的分布图:
为什么要数据对齐呢? 首先是CPU 电脑中的CPU(单核或者多核)对数据对齐有着迫切的追求 一个好的字节长度 可以让CPU运行起来更加的轻松 不好的对齐只会让程序运行的速度减慢 甚至抛出错误
一向以高性能著称的C++语言 早在C++11之前就已经出了控制数据对齐的方法 我现在来介绍几个:
使用宏来获取数据对齐长度:
#include<cstddef>
#define ALIGNOF(type,result) \
struct type##_alignof_trick \
{ \char c; \type member; \
}; \
result=offsetof(type##_alignof_trick,member);
int main()
{int x1=0;ALIGNOF(short, x1);return 0;
}
这段代码看起来比较抽象 难以理解 我来介绍一下:
1.<cstddef>头文件
是C++标准库中的头文件,其中包含了一些与大小和指针相关的类型和函数定义。主要包括以下内容:
std::size_t
:无符号整数类型,用于表示对象的大小或数组的元素数量。std::ptrdiff_t
:带符号整数类型,用于表示指针之间的差值。- 空指针常量(nullptr):用于表示空指针。
offsetof
宏:用于获取结构体成员相对于结构体起始地址的偏移量。此外,该头文件还可能包含其他与指针、数组和内存操作相关的常量、宏和函数定义。
2. type##_alignof_trick
type##_alignof_trick
是一个宏定义中的技巧,通常用于在不支持alignof
运算符的旧版本编译器中获取类型的对齐值。这种技巧通过创建一个包含指定类型的成员变量的结构体,并使用offsetof
宏来计算其偏移量,从而间接地得到类型的对齐值。
3.结构体部分
结构体里面有有一个字符型成员
c
和待测类型的成员变量member
4.\符号
反斜杠(\)被用作换行符的续行符。它允许将一个长的宏定义分成多行以提高可读性。
在C和C++中,反斜杠后面跟着一个换行符会告诉编译器将该宏定义延续到下一行。这样可以将较长的宏定义分解为更易于阅读和理解的多个部分。
在这个代码中使用了多个反斜杠来将
ALIGNOF
宏定义拆分成多行,并确保每行结尾处没有意外的空格或其他字符。这有助于提高代码的可读性和维护性。如果不能使用正确的\ 就会报错
C++11标准之前获取厂商的对齐长度:
在MSVC中,可以使用__alignof
关键字来获取数据类型的对齐长度。例如,要获取整型变量的对齐长度,可以使用以下代码:
#include <iostream>int main() {std::cout << __alignof(int) << std::endl;return 0;
}
GCC
在GCC中,可以使用__alignof__
关键字来获取数据类型的对齐长度。例如,要获取整型变量的对齐长度,可以使用以下代码:
#include <iostream>int main() {std::cout << __alignof__(int) << std::endl;return 0;
}
C++11 统一控制数据对齐长度的方法了
alignof
运算符用于获取给定类型的对齐要求(以字节为单位)。以下是alignof
运算符的使用示例:
#include <iostream>struct MyStruct {int a;char b;
};int main() {std::cout << alignof(int) << std::endl; // 输出:4 (整型的对齐要求通常是4字节)std::cout << alignof(char) << std::endl; // 输出:1 (字符类型的对齐要求通常是1字节)std::cout << alignof(double) << std::endl; // 输出:8 (双精度浮点数的对齐要求通常是8字节)MyStruct obj;std::cout << alignof(MyStruct) << std::endl; // 输出:4 (结构体MyStruct的对齐要求根据其中成员的最大对齐要求而定)return 0;
}
注意alignof运算符不能够测量对象的对齐长度 要想测量对象的对齐长度 使用编译器厂商提供的方法
alignas说明符定义结构体对齐长度
说明 结构体类型的对齐字节长度 总是要大于或者等于结构体成员的对齐长度 如果小于则声明失效
以下为代码实例:
#include <iostream>struct alignas(16) AlignedStruct {int a;char b;
};int main() {alignas(8) int alignedInt; // 将整型alignedInt的对齐要求设置为8字节alignas(double) char alignedCharArray[16]; // 将字符数组alignedCharArray的对齐要求设置为double的对齐要求std::cout << alignof(alignedInt) << std::endl; // 输出:8 (alignedInt的对齐要求)std::cout << alignof(alignedCharArray) << std::endl; // 输出:8 (alignedCharArray的对齐要求)AlignedStruct obj;std::cout << alignof(obj) << std::endl; // 输出:16 (结构体AlignedStruct的对齐要求)return 0;
}
总结:alignas为设置对齐字节长度
alignof为获取字节对齐长度 使用这两个函数 可以人为设置字符对齐字节长度 对CPU的优化达到最大 也可以进行跨平台操作 这在嵌入式linux的应用中显得尤为重要
好了 本篇文章就到这里结束了 在这里 小编向大家推荐一个课程地址:
https://xxetb.xetslk.com/s/2PjJ3T