C++:静态断言内存对齐

静态断言

  • C中的断言assert
    (1)直接参考:https://www.cnblogs.com/lvchaoshun/p/7816288.html
    (2)C的assert是运行时检测发现错误,而不是编译时
    (3)C在编译时错误用#error来输出
  • C++静态断言
    (1)C++引入static_assert(表达式, “提示字符串”)来实现编译时的静态断言
    (2)实例演示
#include <iostream>
#include <type_traits>

// 编译期常量表达式
constexpr int factorial(int n) {
    return (n <= 1) ? 1 : (n * factorial(n - 1));
}

int main() {
    // 编译时断言:检查某些条件是否成立
    static_assert(sizeof(int) == 4, "int 类型的大小不是 4 字节");
    static_assert(factorial(5) == 120, "Factorial 计算错误");
    
    std::cout << "所有静态断言均通过。" << std::endl;

    return 0;
}

#include <iostream>
#include <cassert>

int factorial(int n) {
    assert(n >= 0); // 断言n是非负数
    if (n == 0) {
        return 1;
    } else {
        return n * factorial(n - 1);
    }
}

int main() {
    int num1 = 5;
    int num2 = -3;

    // 正常情况
    std::cout << "Factorial of " << num1 << " is " << factorial(num1) << std::endl;

    // 异常情况(将触发断言)
    std::cout << "Factorial of " << num2 << " is " << factorial(num2) << std::endl;

    return 0;
}

  • 静态断言主要用途
    (1)static_assert主要用于检查模板参数是否符合期望
    (2)C++20中引入了concept来进一步更好的实现模板参数的编译时类型匹配检查

内存对齐

  • C语言中内存对齐关键点
    (1)#pragma 和 attribute((packed)) attribute((aligned(n)))
#include <stdio.h>

// 使用 #pragma pack 控制对齐
#pragma pack(push, 1) // 设置为1字节对齐

typedef struct {
    char c;
    int i;
    double d;
} PackedStruct;

#pragma pack(pop) // 恢复默认对齐

// 使用 __attribute__((packed)) 控制对齐
typedef struct {
    char c;
    int i;
    double d;
} __attribute__((packed)) PackedStructAttribute;

// 使用 __attribute__((aligned(n))) 控制对齐
typedef struct {
    char c;
    int i;
    double d;
} AlignedStruct __attribute__((aligned(16)));

int main() {
    PackedStruct ps;
    PackedStructAttribute psa;
    AlignedStruct as;

    printf("Size of PackedStruct: %zu bytes\n", sizeof(PackedStruct));
    printf("Size of PackedStructAttribute: %zu bytes\n", sizeof(PackedStructAttribute));
    printf("Size of AlignedStruct: %zu bytes\n", sizeof(AlignedStruct));

    printf("Address of ps.c: %p\n", (void*)&ps.c);
    printf("Address of ps.i: %p\n", (void*)&ps.i);
    printf("Address of ps.d: %p\n", (void*)&ps.d);

    printf("Address of psa.c: %p\n", (void*)&psa.c);
    printf("Address of psa.i: %p\n", (void*)&psa.i);
    printf("Address of psa.d: %p\n", (void*)&psa.d);

    printf("Address of as.c: %p\n", (void*)&as.c);
    printf("Address of as.i: %p\n", (void*)&as.i);
    printf("Address of as.d: %p\n", (void*)&as.d);

    return 0;
}

在这里插入图片描述

  • C++中内存对齐新增关键字
    (1)alignof (C++11 起) 查询对齐要求
    (2)alignas (C++11 起)设置对齐,效果:和__attribute__((aligned(n)))效果一样,往大了设置有用
#include <iostream>
#include <cstddef> // for std::size_t

// 使用 alignas 设置对齐
struct alignas(16) AlignedStruct {
    char c;
    int i;
    double d;
};

// 未对齐的结构体
struct UnalignedStruct {
    char c;
    int i;
    double d;
};

int main() {
    // 使用 alignof 查询对齐要求
    std::cout << "Alignment of char: " << alignof(char) << std::endl;
    std::cout << "Alignment of int: " << alignof(int) << std::endl;
    std::cout << "Alignment of double: " << alignof(double) << std::endl;

    std::cout << "Alignment of AlignedStruct: " << alignof(AlignedStruct) << std::endl;
    std::cout << "Alignment of UnalignedStruct: " << alignof(UnalignedStruct) << std::endl;

    // 打印结构体大小
    std::cout << "Size of AlignedStruct: " << sizeof(AlignedStruct) << std::endl;
    std::cout << "Size of UnalignedStruct: " << sizeof(UnalignedStruct) << std::endl;

    // 分配对齐的内存
    void* ptr = aligned_alloc(alignof(AlignedStruct), sizeof(AlignedStruct));
    if (ptr) {
        std::cout << "Memory allocated at address: " << ptr << std::endl;
        free(ptr); // 记得释放内存
    } else {
        std::cerr << "Memory allocation failed!" << std::endl;
    }

    return 0;
}

在这里插入图片描述

  • 什么情况下需要人为改变/指定对齐方式
    (1)往大去对齐。有时候会有一些硬件特殊要求,譬如MMU,cache等。用__attribute__((aligned(n)))实测ok,用#pragma实测不ok
    (2)往下去对齐。有时候需要节省内存而浪费效率,所以希望忽略内存对齐,紧密排放。用#pramgma实测ok,用__attribute__((aligned(n)))实测不ok

总结

了解static_assert的使用方法
了解alignof 、alignas,可以实现内存对齐

学习记录,侵权联系删除。
来源:朱老师物联网大课堂

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/758257.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

华为手机改变休眠时间 不让手机动不动黑屏

在手机中找到设置 并打开 在里面找到显示与亮度 并点开 找到并点击休眠操作项 然后就会弹出 多久进入休眠 可以调久一点

LeetCode 1527, 54,114

目录 1527. 患某种疾病的患者题目链接表要求知识点思路代码 54. 螺旋矩阵题目链接标签思路代码 114. 二叉树展开为链表题目链接标签前序遍历思路代码 前驱思路代码 1527. 患某种疾病的患者 题目链接 1527. 患某种疾病的患者 表 表Patients的字段为patient_id、patient_name…

等保测评练习16

等级保护初级测评师试题16 姓名&#xff1a; 成绩&#xff1a; 一、判断题&#xff08;10110分&#xff09; 1.虚拟机被非法利用后&#xff0c;可能被当作跳板机。&#xff08;T&#xff09; P312 2.云服务商&#xff0c;为云计算服务…

初识 Redis

基础知识网上很多&#xff0c;就不写的太啰嗦&#xff0c;这里纪录一下我的首次使用。 一、redis 安装 在服务器上安装 redis 我的服务器环境是宝塔&#xff0c;方便安装 php 扩展打开 redis 二、项目中的实际应用 首先说明&#xff0c;项目环境是 php redis 的一些基本操…

TypeScript学习笔记(全)

文章目录 TypeScript入门2.编译并运行TS代码2.1.简化运行ts步骤 3.TS中的常用类型3.1.TS中的类型注解3.2.TS中的原始类型3.3.TS中的数组类型3.4.TS中的联合类型3.5.类型别名3.6.函数类型3.6.1.单独执行参数、返回值类型3.6.2.同时指定参数&#xff0c;返回值类型3.6.3.函数的vo…

昇思25天学习打卡营第4天|扩散模型

文章目录 昇思MindSpore应用实践基于MindSpore的Diffusion扩散模型1、Diffusion Models 简介2、构建 Diffusion Model 的准备工作3、Attention 机制4、条件 U-Net5、Diffusion 正向过程6、Diffusion 反向过程7、Diffusion 模型训练 Reference 昇思MindSpore应用实践 本系列文章…

掌握Python编程的深层技能

一、Python基础语法、变量、列表、字典等运用 1.运行python程序的两种方式 1.交互式即时得到程序的运行结果 2.脚本方式把程序写到文件里(约定俗称文件名后缀为.py),然后用python解释器解释执行其中的内容2.python程序运行的三个步骤 python3.8 C:\a\b\c.py 1.先启动python3…

什么是产线工控安全,如何保障产线设备的安全

什么是产线工控安全&#xff1f; 工控&#xff0c;指的是工业自动化控制&#xff0c;主要利用电子电气、机械、软件组合实现。即是工业控制系统&#xff0c;或者是工厂自动化控制。产线工控安全指的是工业控制系统的数据、网络和系统安全。随着工业信息化的迅猛发展&#xff0…

【Lua】第一篇:在Linux系统中安装搭建lua5.4.1环境

文章目录 一. 远程下载安装包二. 解压安装包三. 编译安装Lua环境 一. 远程下载安装包 输入以下命令即可在当前目录下&#xff0c;远程下载安装包lua-5.4.1.tar.gz&#xff1a; wget http://www.lua.org/ftp/lua-5.4.1.tar.gzPS&#xff1a;其他版本的安装包如下&#xff0c;可…

鸿蒙项目实战-月木学途:1.编写首页,包括搜索栏、轮播图、宫格

效果展示 搜索栏制作 相关知识回顾 输入框组件TextInput 单行输入框类型.type(InputType.Normal)//基本输入框.type(InputType.Password)//密码.type(InputType.Email)//邮箱.type(InputType.Number)//数字.type(InputType.PhoneNumber)//电话号.type(InputType.Normal).type…

【折腾手机】一加6T刷机postmarketOS经历和体验

写在前面 到目前为止&#xff0c;我已经花了非常多的时间去学习和了解x86架构和RISC-V架构&#xff0c;对它们的指令集编程、指令格式的设计、编译套件的使用都亲自去体会和实践过&#xff0c;学到了很多的东西。但是对于离我们最近的arm架构却了解甚少。为什么说离我们最近呢…

Python | Leetcode Python题解之第199题二叉树的右视图

题目&#xff1a; 题解&#xff1a; class Solution:def rightSideView(self, root: TreeNode) -> List[int]:rightmost_value_at_depth dict() # 深度为索引&#xff0c;存放节点的值max_depth -1stack [(root, 0)]while stack:node, depth stack.pop()if node is not…

15 个适用于企业的生成式 AI 用例

作者&#xff1a;来自 Elastic Jennifer Klinger 关于生成式人工智能及其能做什么&#xff08;和不能做什么&#xff09;有很多讨论。生成式人工智能&#xff08;例如大型语言模型 - LLMs&#xff09;利用从大量训练数据中学习到的模式和结构来创建原创内容&#xff0c;而无需存…

weiyang**2.部署

一、官方文档 一键部署可以在 同机 快速搭建WeBASE管理台环境&#xff0c;方便用户快速体验WeBASE管理平台。 一键部署会搭建&#xff1a;节点&#xff08;FISCO-BCOS 2.0&#xff09;、管理平台&#xff08;WeBASE-Web&#xff09;、节点管理子系统&#xff08;WeBASE-Node-…

3D生物打印的未来:多材料技术的突破

多材料生物打印技术是近年来发展迅速的一项技术&#xff0c;为组织工程和再生医学带来了新的机遇&#xff0c;可以帮助我们更好地理解人体组织的结构和功能&#xff0c;并开发新的治疗方法。 1. 组织构建 复杂性模拟&#xff1a;多材料生物打印技术能够构建具有层次结构和异质…

2022年第十三届蓝桥杯比赛Java B组 【全部真题答案解析-第二部分】

上一篇文章&#xff1a;2022年第十三届蓝桥杯比赛Java B组 【全部真题答案解析-第一部分】_尘封的CPU的博客-CSDN博客最近回顾了Java B组的试题&#xff0c;深有感触&#xff1a;脑子长时间不用会锈住&#xff0c;很可怕。兄弟们&#xff0c;都给我从被窝里爬起来&#xff0c;赶…

综合项目实战--jenkins节点模式

一、DevOps流程 DevOps是一种方法论,是一系列可以帮助开发者和运维人员在实现各自目标的前提下,向自己的客户或用户交付最大化价值及最高质量成果的基本原则和实践,能让开发、测试、运维效率协同工作的方法。 DevOps流程(自动化测试部分) DevOps完整流程 二、gitee+j…

Burpsuite靶场中信息泄露相关的实验通关

目录 第一关&#xff1a;错误消息中的信息披露 第二关&#xff1a;调试页面信息披露 第三关&#xff1a;通过备份文件披露源代码 第四关&#xff1a;通过信息披露绕过身份验证 第五关&#xff1a;版本控制历史中的信息披露 最近看大佬的文章&#xff0c;发现了很对自己没有…

IOS Swift 从入门到精通:ios 连接数据库 安装 Firebase 和 Firestore

创建 Firebase 项目 导航到Firebase 控制台并创建一个新项目。为项目指定任意名称。 在这里插入图片描述 下一步,启用 Google Analytics,因为我们稍后会用到它来发送推送通知。 在这里插入图片描述 在下一个屏幕上,选择您的 Google Analytics 帐户(如果已创建)。如果没…

FFT的IP核使用报错的检查流程

一、config部分 拉出clk resetn, s_axis_config_tdata&#xff0c; s_axis_config_tready, s_axis_config_tvalid .这四个信号。 时序行为解释&#xff1a;