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

断言和用户提供的消息
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.");
 // ...
 }
// ...
};

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索c++
, 异常
, 断言
static_assert
static assert、static assert用法、c static assert、staticassert头文件、static assert c 11,以便于您获取更多的相关知识。

时间: 2025-01-02 12:28:16

详解C++编程中断言static_assert的使用_C 语言的相关文章

详解C++编程中数组的基本用法_C 语言

可以使用数组下标操作符 ([ ]) 访问数组的各个元素. 如果在无下标表达式中使用一维数组,组名计算为指向该数组中的第一个元素的指针. // using_arrays.cpp int main() { char chArray[10]; char *pch = chArray; // Evaluates to a pointer to the first element. char ch = chArray[0]; // Evaluates to the value of the first e

详解安卓系统中的Android.mk文件_C 语言

概述    Android.mk文件用来向编译系统描述如何编译你的源代码.更确切地说,该文件其实就是一个小型的Makefile.由于该文件会被NDK的编译工具解析多次,因此应该尽量减少源码中声明变量,因为这些变量可能会被多次定义从而影响到后面的解析.这个文件的语法允许把源代码组织成模块,每个模块属于下列类型之一:     APK程序:一般的Android程序,编译打包生成apk文件.     JAVA库:java类库,编译打包生成jar包文件.     C\C++应用程序:可执行的C/C++应用

详解Java编程中的策略模式_java

策略模式属于对象的行为模式.其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换.策略模式使得算法可以在不影响到客户端的情况下发生变化. 策略模式的结构 策略模式是对算法的包装,是把使用算法的责任和算法本身分割开来,委派给不同的对象管理.策略模式通常把一个系列的算法包装到一系列的策略类里面,作为一个抽象策略类的子类.用一句话来说,就是:"准备一组算法,并将每一个算法封装起来,使得它们可以互换".下面就以一个示意性的实现讲解策略模式实例的结构. 这个

详解Java编程中的反射在Android开发中的应用_Android

反射定义 "反射"(Reflection)能够让运行于JVM中的程序检测和修改运行时的行为.为何需要反射 反射带来的好处包括:     在运行时检测对象的类型.     动态构造某个类的对象.     检测类的属性和方法.     任意调用对象的方法.     修改构造函数.方法.属性的可见性. 反射方法Method getDeclaredMethod方法 声明如下: public Method getDeclaredMethod(String name, Class<?>

详解Java编程中向量(Vector)的应用_java

Vector(向量)是 java.util 包中的一个类,该类实现了类似动态数组的功能. 向量和数组相似,都可以保存一组数据(数据列表).但是数组的大小是固定的,一旦指定,就不能改变,而向量却提供了一种类似于"动态数组"的功能,向量与数组的重要区别之一就是向量的容量是可变的. 可以在向量的任意位置插入不同类型的对象,无需考虑对象的类型,也无需考虑向量的容量. 向量和数组分别适用于不同的场合,一般来说,下列场合更适合于使用向量: 如果需要频繁进行对象的插入和删除工作,或者因为需要处理的对

详解Java编程中线程的挂起、恢复和终止的方法_java

有时,线程的挂起是很有用的.例如,一个独立的线程可以用来显示当日的时间.如果用户不希望用时钟,线程被挂起.在任何情形下,挂起线程是很简单的,一旦挂起,重新启动线程也是一件简单的事. 挂起,终止和恢复线程机制在Java 2和早期版本中有所不同.尽管你运用Java 2的途径编写代码,你仍需了解这些操作在早期Java环境下是如何完成的.例如,你也许需要更新或维护老的代码.你也需要了解为什么Java 2会有这样的变化.因为这些原因,下面内容描述了执行线程控制的原始方法,接着是Java 2的方法. Jav

详解Java编程中线程同步以及定时启动线程的方法_java

使用wait()与notify()实现线程间协作 1. wait()与notify()/notifyAll()调用sleep()和yield()的时候锁并没有被释放,而调用wait()将释放锁.这样另一个任务(线程)可以获得当前对象的锁,从而进入它的synchronized方法中.可以通过notify()/notifyAll(),或者时间到期,从wait()中恢复执行. 只能在同步控制方法或同步块中调用wait().notify()和notifyAll().如果在非同步的方法里调用这些方法,在运

详解C语言编程中预处理器的用法_C 语言

预处理最大的标志便是大写,虽然这不是标准,但请你在使用的时候大写,为了自己,也为了后人. 预处理器在一般看来,用得最多的还是宏,这里总结一下预处理器的用法. #include <stdio.h> #define MACRO_OF_MINE #ifdef MACRO_OF_MINE #else #endif 上述五个预处理是最常看见的,第一个代表着包含一个头文件,可以理解为没有它很多功能都无法使用,例如C语言并没有把输入输入纳入标准当中,而是使用库函数来提供,所以只有包含了stdio.h这个头文

详解JavaScript编程中的数组结构_基础知识

数组对象的作用是:使用单独的变量名来存储一系列的值. 创建数组, 为其赋值: 实例 var mycars = new Array(); mycars[0] = "Saab"; mycars[1] = "Volvo"; mycars[2] = "BMW"; 什么是数组?数组对象是使用单独的变量名来存储一系列的值. 如果你有一组数据(例如:车名字),存在单独变量如下所示: var car1="Saab"; var car2=&qu