我试图理解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 assert\n";
assert(2+2==5);
std::cout << "Execution continues past the second assert\n";
_getch();
}
对redundency的评论将受到赞赏(因为我正在学习“如何使用c ++”)
输出cmd
Execution continues past the first assert
Assertion failed: 2+2==5, file c:\users\charles\documents\visual studio 2012\pro
jects\consoleapplication3\consoleapplication3\consoleapplication3.cpp, line 14
我一直试图找出它的不同方法和用法,但据我所知,它是运行时检查和if语句的另一种“类型”
有人可以澄清一下用法并解释每个人做了什么,他们有什么区别?
答案 0 :(得分:3)
您可以将断言视为健全性检查。你知道某些条件应该为真,除非你搞砸了一些东西,所以断言应该通过。如果你确实搞砸了一些东西,那么断言就会失败,你会被告知出了问题。它就是为了确保代码的有效性。
当条件是常量表达式时,可以使用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");
请注意,您通常只希望在调试期间检查运行时断言,因此您可以assert
#define
禁用NDEBUG
。
答案 1 :(得分:1)
在编译时评估static_assert
,在运行时评估assert
。
答案 2 :(得分:1)
我怀疑你找不到任何这方面的资料,但我会给出一些解释。
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");
答案 3 :(得分:1)
assert()
是一个宏,其扩展取决于是否定义了宏NDEBUG
。如果是这样,assert()
不会扩展到任何东西 - 这是一个无操作。如果未定义NDEBUG
,assert(x)
将扩展为运行时检查,如下所示:
if (!x) cause_runtime_to_abort()
在“release”版本中定义NDEBUG
并在“debug”版本中保留未定义是很常见的。这样,assert()
仅在调试代码中执行,并且根本不会使其成为发布代码。您通常使用assert()
来检查应该始终为真的事物 - 例如,函数的前置条件和后置条件或类的不变量。失败的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
}
这样,尝试用例如foo()
拨打float
将导致编译时错误,并显示合理的消息。
有时候,static_assert()
也可以在模板之外使用,例如像这样:
static_assert(sizeof(void*) > 4, "This code does not work in 32 bits");