assert和静态assert函数的使用
use of assert and static assert functions
我正在努力了解static_assert和assert的用法以及它们之间的区别,但关于这个的来源/解释很少
这是一些代码
// ConsoleApplication3.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "conio.h"
#include "cassert"
#include "iostream"
int main()
{
assert(2+2==4);
std::cout << "Execution continues past the first assertn";
assert(2+2==5);
std::cout << "Execution continues past the second assertn";
_getch();
}
对冗余的评论将不胜感激(因为我正在学习"如何c++")
cmd中的输出
Execution continues past the first assert
Assertion failed: 2+2==5, file c:userscharlesdocumentsvisual studio 2012pro
jectsconsoleapplication3consoleapplication3consoleapplication3.cpp, line 14
我一直试图找出它的不同方法和用途,但据我所知,它是一种运行时检查和另一种"类型"的if语句
有人能澄清一下它们的用途,并解释一下每一种的作用和区别吗?
您可以将断言视为健全性检查。您知道某个条件应该为真,除非您搞砸了什么,所以断言应通过。如果您确实搞砸了东西,断言将失败,并且您将被告知出了问题。它只是为了确保代码的有效性。
当条件是常量表达式时,可以使用static_assert
。这基本上意味着编译器能够在程序实际运行之前评估断言。系统会提醒您,static_assert
在编译时失败,而普通的assert
只会在运行时失败。在您的示例中,您可以使用static_assert
,因为表达式2+2==4
和2+2==5
都是常量表达式。
static_assert
对于检查编译时结构(如模板参数)非常有用。例如,您可以断言给定的模板参数T
必须是具有以下内容的POD类型:
static_assert(std::is_pod<T>::value, "T must be a POD type");
请注意,您通常只希望在调试期间检查运行时断言,因此可以通过#define
或NDEBUG
禁用assert
。
assert()
是一个宏,其扩展取决于是否定义了宏NDEBUG
。如果是这样的话,assert()
不会扩展到任何东西——这是一个禁忌。当未定义NDEBUG
时,assert(x)
扩展为运行时检查,类似于以下内容:
if (!x) cause_runtime_to_abort()
通常在"发布"版本中定义NDEBUG
,而在"调试"版本中不定义它。这样,assert()
只在调试代码中执行,根本不会将其转换为发布代码。通常使用assert()
来检查应该始终为true的东西,例如函数的前置条件和后置条件或类的不变量。失败的assert(x)
应该意味着"程序员认为x
成立,但代码中的某个错误(或他们的推理)使这一点不真实。">
static_assert()
(在C++11中引入)是一个关键字,类似于typedef
。它只能用于编译时表达式,如果失败,将导致编译错误。它不会产生任何目标代码,也根本不会被执行。
如果您想防止错误地实例化模板,static_assert()
在模板中非常有用。例如:
template <class IntType>
IntType foo(IntType x)
{
static_assert(std::is_integral<IntType>::value, "foo() may be used with integral types only.");
// rest of the code
}
这样,尝试用例如float
调用foo()
将导致编译时错误,并产生合理的消息。
有时,static_assert()
在模板之外也很有用,例如:
static_assert(sizeof(void*) > 4, "This code does not work in 32 bits");
static_assert
在编译时求值,assert
在运行时求值。
我怀疑你找不到任何来源,但我还是会给出一些解释。
assert
用于永远不会失败的运行时检查。如果失败,程序将不体面地终止。您可以通过指定编译时标志来禁用发布版本的断言。由于断言永远不会失败(毕竟它们是断言),在一个工作程序中,这不应该有任何区别。但是,断言中的表达式不能有副作用,因为不能保证它们被执行。示例:
unsigned int add_non_negative_numbers(int a, int b)
{
// good
assert(a > 0);
assert(b > 0);
return (unsigned int)a + (unsigned int)b;
}
void checked_read(int fd, char *buffer, int count)
{
// BAD: if assertions are disabled, read() will _not_ be called
assert(read(fd, buffer, count) == count);
/* better: not perfect though, because read can always fail
int read_bytes = read(fd, buffer, count);
assert(read_bytes == count);
*/
}
static_assert
是新的,可用于执行编译时检查。当它们失败时会产生编译器错误,并阻止程序编译:
static_assert(sizeof(char) == 1, "Compiler violates the standard");
- "error: no matching function for call to"构造函数错误
- 什么时候调用组成单元对象的析构函数
- 继承函数的重载解析
- 为什么随机数生成器不在void函数中随机化数字,而在main函数中随机化
- C++模板来检查友元函数的存在
- 递归函数计算序列中的平方和(并输出过程)
- 对RValue对象调用的LValue ref限定成员函数
- 我关于函数"Assert"的C++代码有问题
- assert() 在发布模式下充当标识函数吗?
- 如何编写一个接受如下断言消息的自定义断言函数:assert(false) << "assertio
- 能够使用debug.assert()函数需要什么
- 如何使用assert函数
- assert和静态assert函数的使用
- assert()函数未在反汇编中显示
- 在 Xcode [c++] 中在断言 (assert.h) 中定义 lambda 时,为类似函数的宏调用提供过多参数会导
- C++中的函数assert()崩溃
- Assert()函数抛出一个错误——操作符有问题
- 如何避免CRT对话框与assert(.)函数
- assert函数如何在失败时返回文件名和代码行
- 无法解析函数"assert"