alignof 和 alignas各版本异同

学习内容

本节学习 alignof 与 alignas 在各版本的异同,后续请关注 学习C++11/14/17/20/23关键词版本更替 ,将持续更新~~

alignof

C++11引入的编译期运算符,作用是获取一个类型或对象的最小对齐要求(对齐值),返回值是一个std::size_t类型的常量。

计算机为了提升读写效率,要求某些类型的数据必须存储在特定字节倍数地址上,这个特定字节数就是对齐值

cpp 复制代码
cout << "char: " << alignof(char) << endl;       // 输出 1
cout << "int: " << alignof(int) << endl;         // 输出 4(x86_64)
cout << "double: " << alignof(double) << endl;   // 输出 8(x86_64)
cout << "long long: " << alignof(long long) << endl; // 输出 8

struct TData{
	char c;
	int i ;
	double d; } 
cout << alignof(TData) <<endl; // 输出8,结构体中存在的最大对齐值

cout << alignof(int[5]) << endl;  //输出4,仅输出元素类型的对齐值

alignas

C++11引入关键字,核心是显式指定类型、变量或数据成员的内存对齐要求(强制要求数据存储在指定字节倍数的内存地址上)。可以用它提升(无法降低)默认对齐值,或为自定义类型/变量指定更严格的对齐规则(直接要求某类型按照多少字节对齐)

  • 为自定义类型指定对齐,确保其内存布局满足特定要求

    cpp 复制代码
    struct alignas(16) TData{
    	char c;
    	int i;
    	double d;
    };
    
    cout << "TData对齐值" << alignof(TData) << endl;  //16
    cout << " TData大小"<< sizeof(TData) << endl;		 //16
  • 为变量指定对齐,适用于需要特殊内存对齐的场景

    cpp 复制代码
    alignas(32) int arr[4];
    cout << "arr 对齐值 " << alignof(arr) << endl;  // 32
    
    alignas(double) char buf[10];
    cout << " buf 对齐值 " << alignof(buf) << endl;  // 8
  • 为结构体成员指定对齐(C++11起支持 )

    cpp 复制代码
    struct TData{
    	char c;
    	alignas(8) int i;  //i现在是8字节对齐
    	double d;
    
    cout << "TData 对齐值 " << alignof(TData) << endl;  // 8
    cout << "TData 对齐值 " << alignof(TData) << endl;	//必须是最大对齐数的整数倍  24字节
  • 注意 :

    • 不能降低默认对齐,alignas只能指定大于等于类型默认对齐值的数,否则编译器会忽略该设置或报错

      alignas(2) int a; //error int默认是4

    • 多alignas取最大值,如果为同一对象类型指定多个alignas,编译器会取最大的那个

    cpp 复制代码
    struct alignas(8) alignas(16) TData {};  //选用16
    • 参数类型限制,只能是整数常量表达式或类型名

    • 对齐值必须是2的幂

    • 结构体最终大小必须是对齐值的整数倍

C++17 微小优化,无语法变化

  • 允许在static_arrert里自由地使用alignof
cpp 复制代码
static_assert ( alignof(TData) == 8 , "对齐必须是8");
static_assert( alignof(int) == 4 , " int 必须是4 );
  • 修复编译器在类模板、别名模板中的对齐推导

C++20 重要增强

  • alignof变成constexpr表达式,alignof(T)是编译期常量,可以用在任何constexpr环境里

    cpp 复制代码
    constexpr std::size_t s = alignof(int);
  • alignas可用于lambda捕获对象,允许给lambda内部变量指定对齐

  • constexpr上下文中支持对齐检查

    cpp 复制代码
    constexpr bool check() { return alignof(int) == 4 ; }

C++23 小修复

  • 允许在opaque/不完整类型上更安全地使用alignof
  • 统一了不同编译器对空类的对齐规则

opaque指的是不透明类型、不完整类型

不完整类型:

只声明不定义

struct TData; //不完整类型

class MyClass; //不完整类型

void fun(); //函数不是类型

在C++11~C++17之间不能对不完整类型使用alignof

相关推荐
道尔柯南1 分钟前
C++ 面向对象编程入门:类和对象(上)
开发语言·c++·算法
gjf05_058 分钟前
人该怎样活着呢?版本75.8
学习
li星野1 小时前
【学习记录】PCB与PCBA核心知识全解析:从设计到制造的关键细节
学习·制造
aqiu1111112 小时前
【C++算法打怪专栏】C++ `unordered_set` 常用初始化与插入方法总结
开发语言·c++·算法
Terra.K2 小时前
高精度阶乘求和模板深度解析
开发语言·c++·算法
智码看视界2 小时前
C++智能指针全景剖析及面试20问
开发语言·c++·深度学习·面试·内存管理·智能指针
卿卿的产品经理日记2 小时前
【AI产品经理实战】Day 35|从“沉迷工具“到回归 AI 底层:Skill 收官、系统复盘与下一个 13 天
人工智能·学习·产品经理
Peregrine93 小时前
C++ - > 类和对象
java·c++·算法
一条泥憨鱼3 小时前
【从0开始学习计算机网络】| ARP 协议:地址解析,ARP 欺骗,链路层寻址
网络·后端·学习·计算机网络
HY小宝F3 小时前
树莓派智能摄像头系统 30 天重学计划之 Day 04 · HTTP / API:控制链入口 —— 学习总结
网络协议·学习·http