静态断言 static_assert

news2024/11/10 7:44:10

文章链接: https://subingwen.cn/cpp/static_assert/

1. 断言

断言(assertion)是一种编程中常用的手段。在通常情况下,断言就是将一个返回值总是需要为真的判断表达式放在语句中,用于排除在设计的逻辑上不应该产生的情况

比如:一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱。

从一些意义上讲,断言并不是正常程序所必需的,不过对于程序调试来说,通常断言能够帮助程序开发者快速定位那些违反了某些前提条件的程序错误。

如果我们要在C++程序中使用断言,需要在程序中包含头文件<cassert><assert.h>,头文件中为我们提供了 assert 宏,用于在运行时进行断言。举例说明:

#include <iostream>
#include <cassert>
using namespace std;

// 创建一个指定大小的 char 类型数组
char* createArray(int size)
{
    // 通过断言判断数组大小是否大于0
    assert(size > 0);	// 必须大于0, 否则程序中断
    char* array = new char[size];
    return array;
}

int main()
{
    char* buf = createArray(0);
    // 此处使用的是vs提供的安全函数, 也可以使用 strcpy
    strcpy_s(buf, 16, "hello, world!");
    cout << "buf = " << buf << endl;
    delete[]buf;
    return 0;
}

在程序的第9行,使用了断言assert(expression) ,这是一个宏,它的参数是一个表达式,这个表达式通常返回一个布尔类型的值,并且要求表达式必须为 true 程序才能继续向下执行,否则会直接中断。

  • 如果 createArray参数大于0,程序在16行正常运行直到结束
  • 如果 createArray参数小于等于0,程序运行到16行直接退出,会看到如下图的提示信息:

在这里插入图片描述

2. 静态断言

在上面的例子中我们使用了断言 assert。但 assert是一个运行时断言,也就是说它只有在程序运行时才能起作用 。这意味着不运行程序我们将无法得知某些条件是否是成立的。
比如:我们想知道当前是32位还是64位平台,对于这个需求我们应该是在程序运行之前就应该得到结果,如果使用断言显然是无法做到的,对于这种情况我们就需要使用C++11提供的静态断言了。

静态断言static_assert,所谓静态就是在编译时就能够进行检查的断言,使用时不需要引用头文件。静态断言的另一个好处是,可以自定义违反断言时的错误提示信息。静态断言使用起来非常简单,它接收两个参数:

  • 参数1:断言表达式,这个表达式通常需要返回一个 bool值
  • 参数2:警告信息,它通常就是一段字符串,在违反断言(表达式为false)时提示该信息

由于基于VS计算的字节大小和理论值有出入,下面程序基于64位Linux进行测试,使用静态断言验证当前操作系统是否是32位:

// assert.cpp
#include <iostream>                                         
using namespace std;
  
int main()
{
    // 字体原因看起来是一个=, 其实这是两个=
    static_assert(sizeof(long) == 4, "错误, 不是32位平台...");
    cout << "64bit Linux 指针大小: " << sizeof(char*) << endl;
    cout << "64bit Linux long 大小: " << sizeof(long) <<endl;
  
    return 0;
}

通过g++编译程序:

$ g++ assert.cpp -std=c++11
assert.cpp: In function ‘int main()’:
assert.cpp:6:5: error: static assertion failed: 错误, 不是32位平台...
static_assert(sizeof(long) == 4, "错误, 不是32位平台...");

由于使用的Linux是64位的,因此在编译阶段静态断言检测条件失败,提示的错误信息就是我们给静态断言指定的第二个参数对应的那个字符串。

如果我们将静态断言的条件判断修改一下:

static_assert(sizeof(long) == 8, "错误, 不是64位平台...");

然后在进行编译:

$ g++ assert.cpp -std=c++11

编译通过,得到可执行程序a.out,然后执行这个程序可以看到如下输出:

$ ./a.out 
64bit Linux 指针大小: 8
64bit Linux long 大小: 8

静态断言条件判断为true,程序就可以继续向下执行了。

注意事项:
由于静态断言的表达式是在编译阶段进行检测,所以在它的表达式中不能出现变量,也就是说这个表达式必须是常量表达式

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

NeurIPS 2022 | UniAD,一个模型解决所有类别的异常检测!代码已开源

paper&#xff1a;A Unified Model for Multi-class Anomaly Detection&#xff0c;Accepted by NeurIPS 2022. GitHub - zhiyuanyou/UniAD: [NeurIPS 2022] A Unified Model for Multi-class Anomaly Detection Introduction 异常检测已经取得了非常突出的进展。考虑到异常…

测试流程实战

目录&#xff1a; 测试流程梳理业务架构分析实战测试用例管理实战Bug 录入与管理实战如何写 Bug 报告编写 Bug 报告 1.测试流程梳理 2.业务架构分析实战 使用 plantuml 完成雪球 app 登录流程时序图plantuml 官网&#xff1a;使用简单的文字描述画UML图的开源工具。plantuml…

智云通CRM:电子元器件企业优化客户管理的智慧选择

在电子元器件行业&#xff0c;客户管理一直是企业发展的关键所在。如何高效地管理客户&#xff0c;提升销售业绩成为电子元器件企业亟需解决的问题。而智云通CRM作为一款专为企业客户管理和销售管理而生的软件&#xff0c;正成为电子元器件企业优化客户管理的智慧选择。 首先…

vue基础语法

目录 1&#xff1a;vue基础语法 2&#xff1a;内容渲染指令&#xff08;操作标签体中的内容&#xff09; 2.1&#xff1a;v-text指令 2.2&#xff1a;插值语法{{}}语法&#xff1a; 2.3&#xff1a;v-html指令 3&#xff1a;属性绑定指令 4&#xff1a;事件绑定&#xf…

我的大模型观:我眼中的LLM和AIGC

今年&#xff0c;大模型火的一塌糊涂。最近几个月paper with code上&#xff0c;前几名的论文几乎都是生成模型和LLM。参加AI相关的会议&#xff0c;也是千篇一律的LLM。国内的大厂争先恐后的发布自己的大模型&#xff0c;比如百度的文心、360的智脑、讯飞的星火等等&#xff0…

代码随想录算法训练营第三天 | 链表基础系列1-- 链表理论基础-移除链表元素-设计链表-反转链表(203、707、206)

链表基础系列1 链表基础移除链表元素203 移除链表元素代码随想录的代码 707 设计链表我的代码(错误太多&#xff0c;一致debug&#xff0c;没有用虚拟头&#xff0c;不想写了&#xff0c;是未通过的代码)代码随想录的代码小记&#xff1a;双链表好复杂&#xff0c;要仔细看。 2…

【狂神】MySQL - Delete 和 Truncate 的区别

1. DELETE 命令 语法 &#xff1a; delete from 表名 [where 条件] -- 删除数据 (避免这样写, 会全部删除) DELETE FROM student;-- 删除指定数据 DELETE FROM student WHERE id 1; 2. TRUNCATE 命令 作用 : 完全清空一个数据库表, 表的结构和索引约束不会变. -- 清空 stu…

【Linux】LVS+Keepalived高可用负载均衡群集

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 LVSKeepalived高可用负载均衡群集 一、Keepalived实现原理1.Keepalived案例分析2.Keepalived工具介绍3&#xff0c;Keepalived实现原理剖析4.Keepalived案例讲解5.Keepalived…

自媒体新手如何从零开始做自媒体?有哪些步骤流程?

自媒体已经成为了一种非常流行的个人创业方式&#xff0c;相比于传统的创业方式&#xff0c;自媒体的投入成本较低&#xff0c;且门槛较低。许多人都有一个梦想&#xff0c;希望成为一个自媒体人&#xff0c;成为自己的老板。但是&#xff0c;对于很多自媒体小白来说&#xff0…

基于Springboot+mybatis+mysql+vue实现企业注册模块功能

基于Springbootmybatismysqlvue实现企业注册模块功能 一、系统介绍二、功能展示1.主页面2.注册成功 三、数据库四、代码展示四、其他系统实现五、获取源码 一、系统介绍 该系统实现简单的企业信息注册&#xff0c;保存后&#xff0c;提示注册成功。 运行环境&#xff1a;idea…

IP 协议(网络层协议)

IP协议 IP 协议作用地址管理动态分配 IP 地址NAT 机制IPv6IP 地址的组成 路由选择 IP 协议作用 主要有两点 : 地址管理 为每个上网的设备分配一个唯一地址. 路由选择 两台主机间的信息交互, 具体走哪条线路. 地址管理 先来看看 IP协议 报文格式 : IP 协议最主要就是 32 位的…

2.9寸NFC卡片

应用广泛 无需电池 可挂、可横向/纵向摆放&#xff0c;适合多种场所 使用2.9寸电子纸墨水屏&#xff0c;持续显示不耗电 本产品无电池&#xff0c;节能环保&#xff0c;助力实现碳中和 ​ 基于电子纸墨水屏作为显示屏&#xff0c;符合当下节能环保、护眼的需求。质地轻薄、大…

Flameshot (火焰截图)截图无法插入汉字

前不久&#xff0c;Debian11升级至Debian12后&#xff0c;发现fcitx5无法用了&#xff0c;好似包也被删除了。于是重新安装了fcitx5,但发现了一个问题&#xff0c;利用Flameshot&#xff08;火焰截图&#xff09;截取图片时&#xff0c;无法对图片进行文字注释。如下图所示&…

HTML常用标签

1、HTML HTML Hyper Text Markup Language 超文本标记语言 Markup Language 标记语言 XML Extensible Markup Language 可扩展标记语言 HTML2HTML3HTML4XHTML1XHTML2HTML5 2 、HTML基本结构 3 、网页 header header 文档的开始部分 网页加载时&#xff0c;首先加载header…

Spring Cloud Config: 了解、原理和使用

Spring Cloud Config: 了解、原理和使用 Spring Cloud Config 是 Spring Cloud 生态系统中的一个重要组件&#xff0c;它提供了一种分布式配置管理的解决方案&#xff0c;能够集中管理应用程序的配置&#xff0c;支持多种后端存储&#xff0c;如 Git、SVN、本地文件系统、Vaul…

ADG环境下统计每天的归档

现场项目经理反馈&#xff0c;使用日常的归档查询sql看到每天的归档量都快2T了&#xff0c;截图出来确实 很大 查看每天的归档文件总量比当天的归档量少了一半左右&#xff0c;百度了很多案例&#xff0c;最后发现问题该环境是ADG一主一备&#xff0c;每天的归档量也传输到备库…

JavaScript(JS)的引入方法

内部脚本 JS代码必须位于<script></script>标签之间在HTML文档中&#xff0c;可以在任意地方&#xff0c;放置任意数量的<script>一般会把脚本置于<body>元素的底部&#xff0c;可以改善显示速度 外部脚本&#xff1a;将JS代码定义在外部JS文件中&…

0基础学习VR全景平台篇 第55篇:专业版功能-数据统计

使用蛙色VR平台数据统计功能&#xff0c;可以统计分析整个账号下【所有作品】的访问数据&#xff1b; 亦可分析单个作品中【每个场景】的访问数据。 账号数据统计功能位置 单作品数据统计功能位置 一、本功能将用在哪里&#xff1f; 数据统计功能&#xff0c;可实现对作品总访…

自发二元行为预测人际神经同步(INS)的出现

导读 人际神经同步(INS)正在成为预测多人协调、沟通和合作成功等社会互动的有力标志。由于对INS的起源知之甚少&#xff0c;本研究测试了INS是否以及如何从自发的二元行为中产生。要求一对参与者在不说话或做出共同语言手势的情况下互相看着对方&#xff0c;并记录他们的神经活…

网络分层模型以及通信流程

2.1OSI模型和tcp/ip模型 Tcp/ip模型早于ISO的OSI模型 2.2网络为什么要分层&#xff1f; 将一个大的问题进行拆分&#xff0c;分而治之&#xff0c;专门的层处理专门的事情。而且那层出现问题只需对该层进行处理&#xff0c;不会影响到其他层。就相当于做菜的过程&#xff0c;…