1.断言 assert
在C++11中,您可以使用assert
关键字来检查运行时条件是否满足。assert
声明了一个断言,它将在运行时检查给定的条件是否成立。如果条件不成立,将输出一个错误消息并可能终止程序。
在程序中包含头文件<cassert> 或 <assert.h>,头文件中为我们提供了assert宏,用于在运行时进行断言。
作用:用于排除在设计的逻辑上不应该产生的情况
比如:一个函数总需要输入在一定的范围内的参数,那么程序员就可以对该参数使用断言,以迫使在该参数发生异常的时候程序退出,从而避免程序陷入逻辑的混乱
以下是一个使用assert
的示例:
【例子1】
#include <iostream>
#include <cassert>
int main() {
int x = 10;
int y = 20;
assert(x > y);
return 0;
}
在这个例子中,我们使用assert
来检查x
是否大于y
。如果条件不成立,将输出错误消息并可能终止程序。
【例子2】
#include <iostream>
#include <cassert>
#include <string>
#include <string.h>
using namespace std;
// 创建一个指定大小的 char 类型数组
char* createArr(int size) {
// 通过断言判断数组大小是否大于0
assert(size > 0);// 必须大于0,否则程序中断
char* arr = new char[size];
return arr;
}
int main() {
char str[] = "Hello, World!";
char* dest = createArr(0);
copy(str, str + strlen(str), dest);
// strcpy(dest,str);
dest[strlen(str)] = '\0';
delete[] dest;
return 0;
}
heheda@heheda:~/Linux/c++11$ g++ -std=c++11 7.静态断言static_assert.cpp -o app
heheda@heheda:~/Linux/c++11$ ./app
app: 7.静态断言static_assert.cpp:26: char* createArr(int): Assertion `size > 0' failed.
已放弃 (核心已转储)
【总结】断言assert(expression)是一个宏,它的参数是一个表达式。这个表达式通常返回一个布尔类型的值,并且要求表达式必须为 true,程序才能继续向下执行,否则会直接中断。
2.静态断言
静态断言(static_assert
)是C++11中引入的一个编译时检查工具,用于检查编译时条件是否满足。与assert
不同,静态断言不会导致程序终止,而只是生成一个编译时错误。当条件不满足时,静态断言将输出一个错误消息。
静态断言
① 在编译时能够进行检查的断言
② 使用时不需要引用头文件
③ 可以自定义违反断言时的错误提示信息
④ 使用起来非常简单,它接收两个参数
- 参数1:断言表达式,这个表达式通常需要返回一个 bool值
- 参数2:警告信息,它通常就是一段字符串,在违反断言(表达式为false)时提示该信息
static_assert
的参数分为两部分:一个是条件,另一个是错误消息。
🦝① 条件是一个布尔式,用于检查编译时条件是否满足
🦝② 错误消息是一个字符串,用于描述不满足条件的情况
static_assert(condition, message);
例如:
static_assert(sizeof(int) < sizeof(unsigned int), "int is not smaller than unsigned int");
在这个例子中,我们使用了静态断言来检查int
的大小是否小于unsigned int
的大小,如果不成立,将输出错误消息 "int is not smaller than unsigned int"。
在C++11中,您可以使用static_assert
来检查编译时条件是否满足。static_assert
声明了一个静态断言,它将在编译时检查给定的条件是否成立。如果条件不成立,将引发编译时错误。
以下是一个使用static_assert
检查整数类型大小的示例:
【例子1】
#include <iostream>
#include <type_traits>
template <typename T>
void print_size() {
std::cout << "Size of " << typeid(T).name() << ": " << sizeof(T) << std::endl;
}
int main() {
print_size<int>();
print_size<unsigned int>();
print_size<long long>();
static_assert(sizeof(int) < sizeof(unsigned int), "int is not smaller than unsigned int");
return 0;
}
在这个例子中,我们定义了一个名为print_size
的模板函数,它接受一个类型参数T
。在main
函数中,我们调用print_size
来打印类型int
,unsigned int
和long long
的大小。然后,我们使用static_assert
来检查int
的大小是否小于unsigned int
的大小,如果不成立,将引发编译时错误。
静态断言表达式的结果是一个布尔值。如果表达式为真,那么程序将继续正常编译和运行。如果表达式为假,那么程序将因为断言失败而终止。因此,静态断言表达式应该确保编译时条件成立,以便正确编译程序。
#include <iostream>
using namespace std;
int main() {
// static_assert(sizeof(long) == 4, "错误, 不是32位平台"); // error: static assertion failed: 错误, 不是32位平台
static_assert(sizeof(long) == 8, "错误, 不是32位平台");
cout << "64bit Linux 指针大小: " << sizeof(char*) << endl;
cout << "64bit Linux long 大小: " << sizeof(long) <<endl;
return 0;
}
在64位的Linux操作系统下,运行这个程序。如果static_assert的条件是sizeof(long) == 4,那么会编译的时候会出现如下错误:
如果static_assert的条件是sizeof(long) == 8,那么编译不会出错
64bit Linux 指针大小: 8
64bit Linux long 大小: 8
🦥静态断言与断言的区别:
🦝① assert是一个运行时断言,只有在程序运行时才能起作用。也就是说不运行程序就无法得知某些条件是否是成立的。
🦝② 静态断言的表达式是在编译阶段进行检测
【注意点】
🦝① 由于静态断言的表达式是在编译阶段进行检测,所以在它的表达式中不能出现变量,也就是说这个表达式必须是常量表达式。
🦝② 静态断言的条件不能包含函数调用、成员访问或其他运行时操作,因为这些操作只能在运行时执行,而静态断言是在编译时检查条件。