详解C++编程中断言static_assert的使用


断言和用户提供的消息
C++ 语言支持可帮助您调试应用程序的三个错误处理机制:#error 指令、static_assert 关键字和 assert (CRT) 宏。所有的三种机制都会发出错误消息,其中两个还会测试软件断言。软件断言指定在程序的某个特定点应满足的条件。如果编译时断言失败,编译器将发出诊断消息和编译错误。如果运行时断言失败,操作系统将发出诊断消息并关闭应用程序。
备注
应用程序的生存期由预处理、编译和运行时阶段组成。每个错误处理机制都会访问在这三个阶段之一中可用的调试信息。若要有效地调试,请选择提供有关该阶段的相应信息的机制:
#error 指令在预处理时有效。它将无条件地发出用户指定的消息并导致编译因错误而失败。该消息可包含由预处理器指令操作的文本,但不会计算任何生成的表达式。
static_assert 声明在编译时有效。它将测试由用户指定且可以转换为布尔值的整数表达式表示的软件断言。如果表达式的计算结果为零 (false),编译器将发出用户指定的消息,并且编译因错误而失败。
static_assert 声明对调试模板尤其有用,因为模板参数可包含在用户指定的表达式中。
assert (CRT) 宏在运行时有效。它会计算用户指定的表达式,如果结果为零,系统将发出诊断消息并关闭应用程序。很多其他宏(如_ASSERT 和 _ASSERTE)与此宏类似,但它们发出不同的系统定义或用户定义的诊断消息。

static_assert
在编译时测试软件断言。如果指定的常量表达式为 false,则编译器显示指定的消息,并且编译失败,错误为 C2338;否则,声明不起作用。
语法

static_assert( 
 constant-expression, 
 string-literal 
);

参数

参数 说明
constant-expression 可以转换为布尔值的整型常量表达式。如果计算出的表达式为零 (false),则显示 string-literal 参数,并且编译因出错而失败。如果表达式不为零 (true),则 static_assert 声明无效。
string-literal 当 constant-expression 参数为零时显示的消息。该消息是编译器的基本字符集中的一个字符串;即,不是多字节或宽字符。

备注
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 声明具有命名空间范围。由于编译器知道类型 void * 的大小,因此可以立即计算表达式。
示例

static_assert(sizeof(void *) == 4, "64-bit code generation is not supported.");

说明
在下面的示例中,static_assert 声明具有类范围。 static_assert 验证模板参数是否为纯旧数据 (POD) 类型。编译器将在声明 static_assert 声明时检查该声明,但不计算 constant-expression 参数,直到在 main() 中实例化 basic_string 类模板。
示例

#include <type_traits>
#include <iosfwd>
namespace std {
template <class CharT, class Traits = std::char_traits<CharT> >
class basic_string {
 static_assert(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() {}
};
int main()
{
 std::basic_string<char> bs;
}

说明
在下面的示例中,static_assert 声明具有块范围。 static_assert 验证 VMPage 结构的大小是否与该系统的虚拟内存页大小相等。
示例

#include <sys/param.h> // defines PAGESIZE
class VMMClient {
public:
 struct VMPage { // ... 
   };
 int check_pagesize() {
 static_assert(sizeof(VMPage) == PAGESIZE,
  "Struct VMPage must be the same size as a system virtual memory page.");
 // ...
 }
// ...
};



相关阅读:
JavaScript程序员应该知道的45个实用技巧
MySQL错误ERROR 1615 解决方法
javascript实现点击商品列表checkbox实时统计金额的方法
javascript中键盘事件用法实例分析
MySQL中select语句介绍及使用示例
浅析JavaScript中的delete运算符
Android新浪微博下拉刷新(最新消息显示在最上面)
php异常处理使用示例
C#批量更新sql实例
js 3种归并操作的实例代码
浅析Android手机卫士手机定位的原理
php去除数组中重复数据
Android实现判断某个服务是否正在运行的方法
css的margin collapsing导致最上面会出现一个横条
快速导航
PHP MySQL HTML CSS JavaScript MSSQL AJAX .NET JSP Linux Mac ASP 服务器 CMS SQL jQuery C# C++ java Android IOS oracle MongoDB PostgreSQL SQLite 交通频道 临安-果洛 莱芜-牡丹江 大庆-黄南 牡丹江-台州 蓬莱-鄂尔多斯 滕州-运城 承德-六盘水 增城-保山 邵阳-苍南 温州-柳州 珠海-海宁 广元-赤峰 中卫-桓台 朝阳-吉林 北京-白山 攀枝花-铜川 成都-和田 临汾-曲靖 白银-宜兴 盘锦-宁波 舟山-南昌 宁海-蓬莱 荥阳-嘉峪关 安阳-阿勒泰 本溪-通辽 铜川-诸城 常熟-玉环 亳州-汕尾 无锡-洛阳 桐乡-即墨 新余-珠海 丹东-安宁 莱州-益阳 沈阳-淄博 昌都-湘潭 南充-云浮 泸州-普洱 新泰-营口 平度-仙桃 上海-拉萨 吉林-朔州 大石桥-锦州 渭南-随州 阜阳-玉林 黄南-防城港 齐齐哈尔-桂林 黄山-义马 广安-晋中 东营-安庆 三门峡-河池 嵊州-清远 宣城-蓬莱 北京-贵港 阿里-石家庄 鄂州-资阳 随州-湘潭 韶关-南安 玉溪-晋江 双流-中卫 宜兴-邵阳 江阴-娄底 都江堰-扬州 合肥-章丘 汉中-山南 辽阳-湖州 保山-钦州 通化-新密 邵阳-章丘 瓦房店-周口 大理-扬州 保定-六盘水 天津-镇江 宜兴-沧州 巢湖-鄂尔多斯 普兰店-嘉善 永康-宁乡 肥城-玉环 巢湖-眉山 果洛-承德 启东-南通 肃宁-西平 镇江-沈阳北 淄博-双城北 边沟-灌水 铁力-大庆 东明县-菏泽 苏家屯-沧州 侯马-永济 上饶-南昌西 井冈山-罗平 郑州西-常州北 秦皇岛-保康 新化-菏泽 定州-慈利 余杭-贵阳北 惠州-长沙 罗山-上海 开封-赤壁 镇赉-镇安 永州-沈阳北 玉林-博白 临城-大同 福清-铜仁南 山市-杨岗 锦州-东营子 雅鲁-碾子山 德州-吴堡 松树-三江口 青田-商洛 平顶山西-德惠 淮滨-咸宁 义乌-达州 永修-永泰 广安-安阳 黄口-郴州 临汾-太原东 福州-嘉峪关 华蓥-天津 旬阳-徐水 新民-洮南 全椒-合肥 抚州东-厦门北 武汉-白洋淀 娄底-郑州 冯屯-绥棱 和平-鹰潭 马鞍山-丹阳 株洲西-汉口 进贤南-衢州 巢湖东-郴州西 乐都-吉安 罗源-上海虹桥 鹤壁-洛阳 平原-山城镇 古田北-江山 南昌-宣汉 赵城-繁峙 民权-枣庄西 民权-定西 玉林-贵定南 盘锦北-白沟 通辽-沙海 兰家屯-沈阳 洛阳-咸阳 洛阳-向塘 中和-下马塘 海城-太阳升 桂林西-恭城 岑溪-湘潭 兰考南-绩溪北 绥德-沈阳北 麻山-黑台 东光-兖州 大盘石-艾河 兰州-黄羊镇 江宁-青田 南昌西-盘锦 广元-德令哈 劲松-冯屯 开道-一面坡

Copyright © 2016 phpStudy |