C++断言与静态断言

deltamaster posted @ Sep 22, 2011 01:20:59 PM in C++ with tags C++ assert 断言 静态断言 , 7088 阅读

  断言是很早之前就有的东西了,只需要引入cassert头文件即可使用。往往assert被用于检查不可能发生的行为,来确保开发者在调试阶段尽早发现“不可能”事件真的发生了,如果真的发生了,那么就表示代码的逻辑存在问题。最好的一点就是,断言只在Debug中生效,因此对于Release版本是没有效率上的影响的。

 

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

int main() {
	int i = 22;
	assert(i != 22);
	system("pause");
	return 0;
}

  上面的代码就表示,你确认在这里i一定不会等于22,如果事实上真的是22,那么程序就会无情地被abort,并报告出现问题的源文件和行号(使用了魔法常量__FILE__和__LINE__),有助于及时定位问题。

  断言有一个问题,就是一定会abort,强制整个程序退出而导致调试也无法继续进行,就像上图这样,出现问题后,我们知道了出现问题的行号,但是我们需要手动在该行的上面设置断点,重新开始调试才能够检查到发生问题时各个变量的状态。而且,有时问题不是那么容易重现,于是就可能出现没法重现错误再检查状态的问题。

  所以,我们可以自己写一个类似的宏来解决这个问题,我们希望在违反断言时触发断点陷阱门中断而不是调用abort,这样,在违反断言时程序会暂停下来,等待程序员来检查当前的状态有何异常。

  下面是一个Visual C++中的实现。

 

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

#define _ASSERT(x) if (!(x)) __asm {int 3};

int main() {
	int i = 22;
	//assert(i != 22);
	_ASSERT(i != 22);
	system("pause");
	return 0;
}

  上面定义了一个宏,名字当然可以自己取,实际上做的一件事就是检查断言,然后如果断言结果为false(0),那么就调用内联汇编指令int 3陷入调试中断。

  在2011年的C++标准中出现了静态断言(static_assert)的语法,所谓静态断言,就是在编译时就能够进行检查的断言,static_assert是C++的标准语法,不需要引用头文件。静态断言的另一个好处是,可以自定义违反断言时的编译错误信息。

 

#include <iostream>
using namespace std;

int main() {
	const int i = 22;
	static_assert(i != 22, "i equals to 22");
	system("pause");
	return 0;
}

  这个代码,将无法通过编译,因为i的值违反了静态断言。

  静态断言的限制是,断言本身必须是常量表达式,如果这样的i不是常量,静态断言是不符合语法的。

 

* 本文在CC BY-SA(署名-相同方式共享)协议下发布。
charlly 说:
Dec 28, 2022 03:40:29 PM

There are two main types of assertions in C++: assertions and static assertions. Assertions are typically used to check for programmer errors, and static assertions are used to check for errors that can be detected at compile time. Static assertions are generally more efficient and easier to use, gout remedies but they can only be used in certain situations.

celeb networth 说:
Jun 11, 2023 12:20:22 PM

Finally find the info someone asked the other day about Johnny Depp on celeb height wiki I was looking for it all over the web and luckily found it!


登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter