C++中#error/assert/static_assert的区别及使用
C++ 语言支持可帮助您调试应用程序的三个错误处理机制:#error 指令、static_assert 关键字和 assert (CRT) 宏。所有的三种机制都会发出错误消息。
#error可看做预编译期断言,甚至都算不上断言,仅仅能在预编译时显示一个错误信息,它能做的不多,可以参与预编译的条件检查,由于它无法获得编译信息,当然就做不了更进一步分析了。使用#error方法是非常烦琐的,并且不能够对模板参数进行检查,因为模板实例化是在编译时进行,而#error方法是在预处理阶段进行的。
#error 指令在预处理时有效。它将无条件地发出用户指定的消息并导致编译因错误而失败。该消息可包含由预处理器指令操作的文本,但不会计算任何生成的表达式。
assert是运行期断言,它用来发现运行期间的错误,不能提前到编译期发现错误,也不具有强制性,也谈不上改善编译信息的可读性,既然是运行期检查,对性能当然是有影响的,所以经常在发行版本中,assert都会被关掉。
assert (CRT) 宏在运行时有效。它会计算用户指定的表达式,如果结果为零,系统将发出诊断消息并关闭应用程序。
static_assert语法:static_assert(constant-expression,string-literal);
static assert is used to make assertions at compile time. When the static assertion fails, the program simply doesn't compile.
static_assert这个宏用于检测和诊断编译时错误。编译期,这是一个与 CRT-assert(运行时宏)相反的宏。这个宏用于检测编译时程序的不变量。static_asset 是在编译时执行的,不能用于检测运行时的值。而断言assert宏只有在程序运行时才能起作用。
static_assert宏,在编译时测试软件断言。如果指定的常量表达式为false,则编译器显示指定的消息,并且编译失败,错误为 C2338;否则,声明不起作用。
static_assert 声明的constant-expression 参数表示软件断言。软件断言指定在程序的某个特定点应满足的条件。如果满足该条件,则 static_assert 声明无效。如果未满足该条件,则断言失败,编译器在 string-literal 参数中显示消息,并且编译因出错而失败。
static_assert 声明在编译时测试软件断言。相反,assert (CRT) 宏在运行时测试软件断言,并会导致增大运行时花费的空间和时间。由于模板参数包含在constant-expression 参数中,因此 static_assert 声明对于调试模板很有用。
当遇到声明时,编译器将检查static_assert 声明是否存在语法错误。如果编译器不依赖于模板参数,则编译器会立即计算 constant-expression 参数。否则,在对模板进行实例化时,编译器将计算 constant-expression 参数。因此,当遇到声明时,编译器可能一次发布一个诊断消息,而在对模板进行实例化时也是如此。
可以在命名空间、类或块范围中使用static_assert 关键字。(由于 static_assert 关键字可以在命名空间范围内使用,因此,即使它不将新名称引入程序中,但从技术上讲,它也是一个声明。)
使用static_assert,我们可以在编译期间发现更多的错误,用编译器来强制保证一些契约,并帮助我们改善编译信息的可读性,尤其是用于模板的时候。static_assert可以用在全局作用域中,命名空间中,类作用域中,函数作用域中,几乎可以不受限制的使用。编译器在遇到一个static_assert语句时,通常立刻将其第一个参数作为常量表达式进行演算,但如果该常量表达式依赖于某些模板参数,则延迟到模板实例化时再进行演算,这就让检查模板参数成为了可能。
由于static_assert是编译期间断言,不生成目标代码,因此static_assert不会造成任何运行期性能损失。
static_assert声明在编译时有效。它将测试由用户指定且可以转换为布尔值的整数表达式表示的软件断言。如果表达式的计算结果为零 (false),编译器将发出用户指定的消息,并且编译因错误而失败。static_assert 声明对调试模板尤其有用,因为模板参数可包含在用户指定的表达式中。
以下是测试代码:
static_assert.hpp:
#ifndef FBC_MESSY_TEST_STATIC_ASSERT_HPP
#define FBC_MESSY_TEST_STATIC_ASSERT_HPP#ifndef __cplusplus#error static_assert.hpp header must be compiled as C++
#endif#include <type_traits>
#include <iosfwd>
#include <cassert>// reference: https://msdn.microsoft.com/zh-cn/library/dd293588.aspx// static_assert 声明具有类范围。 static_assert 验证模板参数是否为纯旧数据 (POD) 类型。
// 编译器将在声明 static_assert 声明时检查该声明,但不计算 constant-expression 参数,直到在 main() 中实例化 basic_string 类模板
template <class CharT, class Traits = std::char_traits<CharT> >
class basic_string {static_assert(std::tr1::is_pod<CharT>::value, "Template argument CharT must be a POD type in class template basic_string");// ...
};struct NonPOD {NonPOD(const NonPOD &) {}virtual ~NonPOD() {}
};// reference: http://stackoverflow.com/questions/1647895/what-does-static-assert-do-and-what-would-you-use-it-for
class Foo
{
public:static const int bar = 5; // 3
};static_assert(Foo::bar > 4, "Foo::bar is too small :(");void test_static_assert1();
void test_static_assert2();
void test_static_assert3();
void test_static_assert4(int a);#endif // FBC_MESSY_TEST_STATIC_ASSERT_HPP
static_assert.cpp:#include "static_assert.hpp"void test_static_assert1()
{// static_assert 声明具有命名空间范围。由于编译器知道类型 void * 的大小,因此可以立即计算表达式//该static_assert用来确保编译仅在32位的平台上进行,不支持64位的平台//static_assert(sizeof(void *) == 4, "64-bit code generation is not supported."); // sizeof(void *) = 8 ?
}void test_static_assert2()
{basic_string<char> bs;
}void test_static_assert3()
{Foo::bar;
}void test_static_assert4(int a)
{assert(a / 2 == 0);
}
主要参考文献:
1. https://msdn.microsoft.com/zh-cn/library/dd293588.aspx
GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:

读完ACL 2019录取的30篇知识图谱论文,我发现了这5点趋势
作者 | Michael Galkin译者 | Freesia编辑 | 夕颜出品 | AI科技大本营(ID: rgznai100)【导读】近年来,自然语言处理领域中广泛应用的知识图谱(KGs)正在不断地吸引人们的目光,此次 ACL 2019 中的有关于知识图…

力扣(LeetCode)933
题目地址:https://leetcode-cn.com/probl...题目描述:写一个 RecentCounter 类来计算最近的请求。 它只有一个方法:ping(int t),其中 t 代表以毫秒为单位的某个时间。 返回从 3000 毫秒前到现在的 ping 数。 任何处于 [t - 3000, …

2013年10月1日C#随机数
最近开始接触C跟C#,总是有人说女生本来就不适合做程序,就连今天都听到有人这样跟我讲,不过呢没有关系,我相信男生不一定比女生厉害多少,就好像我身边就有一位男生就总是觉得我的程序比他好一点就是理所当然的ÿ…

C/C++中inline/static inline/extern inline的区别及使用
引入内联函数的目的是为了解决程序中函数调用的效率问题,也是用内联函数取代带参宏定义(函数传参比宏更加方便易用)inline关键字用来定义一个类的内联函数。在类体中和类体外定义成员函数是有区别的:在类体中定义的成员函数为内联…

RISC-V架构上的Debian和Fedora现状
RISC-V仍然是开源/Linux用户非常感兴趣的,因为它是免版税且完全开放的CPU架构。部分原因是由于缺乏经济实惠的RISC-V硬件,限制了开发人员在这种架构上的更多工作,Linux发行版支持的RISC-V状态各不相同,但近年来至少有所改善。在上…

字节跳动李航:自学机器学习,研究AI三十载,他说AI发展或进入平缓期
作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)【导读】一阵凉风吹过人工智能,让这个曾是燥热的领域逐渐冷却下来,留下的是扎实地在做研究的人、机构、企业。先后在 NEC 公司中央研究所、微软亚洲研究院、华为诺亚方舟实验室从事和…

PC上安装MAC X Lion
PC上安装MACXLion网上关于如何在PC下安装MAC的文章已近不少了,但对于一些初学者在实践当中会遇到各种问题,以下视频资料为大家展示两种虚拟机安装MacOS。1.VmwareWorkstation在虚拟机中安装首先将插件装好(在远景上下载)ÿ…

C++中static_cast/const_cast/dynamic_cast/reinterpret_cast的区别和使用
C风格的强制转换较简单,如将float a转换为int b,则可以这样:b (int)a,或者bint(a)。 C类型转换分为隐式类型转换和显示类型转换。 隐式类型转换又称为标准转换,包括以下几种情况: (1)、算术转换&#x…

行为型模式:命令模式
LieBrother原文: 行为型模式:命令模式 十一大行为型模式之三:命令模式。 简介 姓名 :命令模式 英文名 :Command Pattern 价值观 :军令如山 个人介绍 : Encapsulate a request as an object,ther…

与旷视、商汤等上百家企业同台竞技?AI Top 30+案例评选等你来秀!
人工智能历经百年发展,如今迎来发展的黄金时期。目前,AI 技术已涵盖自然语言处理、模式识别、图像识别、数据挖掘、机器学习等领域的研究,在汽车、金融、教育、医疗、安防、零售、家居、文娱、工业等行业获得了令人印象深刻的成果。在各行业宣…

在CSS中定义a:link、a:visited、a:hover、a:active顺序
摘自:http://www.qianyunlai.com/post-2.html以前用CSS一直没有遇到过这个问题,在最近给一个本科同学做的项目里面。出现一些问题,搜索引擎查了一些网站和资料,发现很多人问到这个问题,给出的结果我试了试,…
C++中istream的使用
在项目中会经常用到读取一些配置数据,这些数据根据实际需要有可能会调整,如果将这些数据直接嵌入进代码中会非常不便,需要经常调整代码。将这些数据写入配置文件中然后在读入,如果需要调整,只需修改配置文件࿰…

手把手教你用Python模拟登录淘宝
作者 | 猪哥66来源 | 裸睡的猪(ID:IT--Pig)最近想爬取淘宝的一些商品,但是发现如果要使用搜索等一些功能时基本都需要登录,所以就想出一篇模拟登录淘宝的文章!看了下网上有很多关于模拟登录淘宝,但是基本都…

Python之机器学习K-means算法实现
一、前言: 今天在宿舍弄了一个下午的代码,总算还好,把这个东西算是熟悉了,还不算是力竭,只算是知道了怎么回事。今天就给大家分享一下我的代码。代码可以运行,运行的Python环境是Python3.6以上的版本&#…

C++中模板的使用
模板(Template)指C程序设计语言中的函数模板与类模板,是一种参数化类型机制。模板是C泛型编程中不可缺少的一部分。C templates enable you to define a family of functions or classes that can operate on different types of information.模板就是实现代码重用机…
php面试问答
结合实际PHP面试,汇总自己遇到的问题,以及网上其他人遇到的问题,尝试提供简洁准确的答案包含MySQL、Redis、Web、安全、网络协议、PHP、服务器、业务设计、线上故障、个人简历、自我介绍、离职原因、职业规划、准备问题等部分 GitHub: https:…

图解LSTM与GRU单元的各个公式和区别
作者 | Che_Hongshu来源 | AI蜗牛车 (ID: AI_For_Car)因为自己LSTM和GRU学的时间相隔很远,并且当时学的也有点小小的蒙圈,也因为最近一直在用lstm,gru等等,所以今天没事好好缕了一下,接下来跟着我一起区分并…

iphone越狱神器
前阵子刚刚换了iphone5,老婆的4就留给我了。一到手就决定越狱,无意中发现了一款越狱神器:爱思助手http://www.i4.cn/ 确实很好用转载于:https://blog.51cto.com/shanks/1306423
json11库的使用
JSON(JavaScript Object Notation)是一种轻量级的文本数据交换格式,易于让人阅读。同时也易于机器解析和生成。尽管JSON是Javascript的一个子集,但JSON是独立于语言的文本格式,并且采用了类似于C语言家族的一些习惯。JSON解析器和JSON库支持许…
覆盖10亿设备,月活2亿,快应用要取代App?
作者 | 伍杏玲 来源 | CSDN(ID:CSDNnews) 2017 年 1 月 9 日,微信小程序横空出世,紧接着支付宝小程序、百度智能小程序、今日头条小程序、12 大厂商联盟的快应用等布局小程序。自此,小程序迅速改变国内移…

跨域的四种方式
本文主要是关于跨域的几种方式,关于什么是跨域这里就不多说了,写这个也是为了记住一些知识点的。 一. jsonp jsonp的跨域方式很容易理解,页面的的每一个script标签浏览器都会发送get请求获取对应的文本资源,获取到了之后ÿ…

使用模式创建一个面向服务的组件中间件
引言 在本文中,您将了解面向服务的组件中间件在用于资源有限的语音设备时,在设计阶段所应用的模式。它涵盖了项目的问题上下文,并被看成是一组决定因素,是对相关体系结构远景的一个简要概括。您还会得到一份描述,其中介…

OpenCV代码提取:遍历指定目录下指定文件的实现
OpenCV 3.1之前的版本,在contrib目录下有提供遍历文件的函数,用起来比较方便。但是在最新的OpenCV 3.1版本给去除掉了。为了以后使用方便,这里将OpenCV 2.4.9中相关的函数给提取了出来,适合在Windows 64bits上使用。directory.hpp…

姚班三兄弟3万块创业八年,旷视终冲刺港股
作者 | 余洋洋 杨健楷编辑 | 张丽娟来源 | CV智识(ID:CVAI2019)旷视此次 IPO 或将成为整个 AI 行业的信号,不只是“ 四小龙”的另外三家——商汤、依图、云从,整个 AI 行业的创业公司都将受到影响。8月25日晚,AI 独角兽…
Java类加载器详解
Java虚拟机中的类加载有三大步骤:,链接,初始化.其中加载是指查找字节流(也就是由Java编译器生成的class文件)并据此创建类的过程,这中间我们需要借助类加载器来查找字节流. Java虚拟…

linux svn客户端的使用
一下内容转载于:http://blog.chinaunix.net/space.php?uid22976768&doblog&id1640924。这个总结的很好~ windows下的TortoiseSVN是资源管理器的一个插件,以覆盖图标表示文件状态,几乎所以命令都有图形界面支持,比较好用&…

C++中vector的使用
向量std::vector是一种对象实体,能够容纳许多各种类型相同的元素,包括用户自定义的类,因此又被称为序列容器。与string相同,vector同属于STL(Standard Template Library)中的一种自定义的数据类型,可以广义上认为是数组…

说出来你可能不信,现在酒厂都在招算法工程师
导语:虽然夏日已过,但人们喝啤酒的热情还在持续高涨。不过随着大众的追求和理念提升,对于啤酒的要求也越来越高,比如逐渐兴起的精酿之风,都在印证人们在啤酒的口感和风味上,拥有更加「苛刻」的要求。那么这…
「前端面试题系列7」Javascript 中的事件机制(从原生到框架)
前言 这是前端面试题系列的第 7 篇,你可能错过了前面的篇章,可以在这里找到: 理解函数的柯里化ES6 中箭头函数的用法this 的原理以及用法伪类与伪元素的区别及实战如何实现一个圣杯布局?今日头条 面试题和思路解析最近,…

安装Ecshop首页出现报错:Only variables should be passed by referen
出现下面这就话: Strict Standards: Only variables should be passed by reference in D:\wamp\ecshop\includes\cls_template.php on line 406 第406行:$tag_sel array_shift(explode( , $tag)); 解决办法 1 5.3以上版本的问题,应该也和配…