1

我正在尝试了解 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();
}

对冗余的评论将不胜感激(因为我正在学习“如何使用 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 语句的另一种“类型”

有人可以澄清用途并解释每个人的作用和它们的区别吗?

4

4 回答 4

3

您可以将断言视为健全性检查。你知道某些条件应该为真,除非你搞砸了,所以断言应该通过。如果你确实把事情搞砸了,断言就会失败,你会被告知有什么问题。它只是为了确保您的代码的有效性。

static_assert当条件为常量表达式时,可以使用A。这基本上意味着编译器能够在程序实际运行之前评估断言。您将被警告 astatic_assert在编译时失败,而 normalassert只会在运行时失败。在您的示例中,您可以使用static_assert, 因为表达式2+2==42+2==5都是常量表达式。

static_asserts 对于检查诸如模板参数之类的编译时构造很有用。例如,您可以断言给定的模板参数T必须是 POD 类型,具有以下内容:

static_assert(std::is_pod<T>::value, "T must be a POD type");

请注意,您通常只希望在调试期间检查运行时断言,因此您可以assert通过#defineing禁用NDEBUG

于 2014-01-17T10:42:06.400 回答
2

assert()是一个宏,其扩展取决于是否NDEBUG定义了宏。如果是这样,assert()则不会扩展到任何内容-这是无操作的。当NDEBUG未定义时,assert(x)扩展为运行时检查,如下所示:

if (!x) cause_runtime_to_abort()

NDEBUG在“发布”版本中定义并在“调试”版本中未定义是很常见的。这样,assert()s 仅在调试代码中执行,根本不使其成为发布代码。您通常assert()用来检查应该始终为真的事物——例如,函数的前置条件和后置条件或类的不变量。失败assert(x)应该意味着“程序员认为这是x成立的,但代码(或他们的推理)某处的错误使这不真实。”


static_assert() (which was introduced in C++11) is a keyword - similar to e.g. typedef. It can only be used on compile-time expressions, and if it fails, it results in a compilation error. It does not result in any object code and is not executed at all.

static_assert() is primarily useful in templates, if you want to prevent instantiating a template incorrectly. For example:

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
}

That way, trying to call foo() with e.g. a float will result in a compile-time error with a sensible message.

Occasionally, static_assert() can also be useful outside of templates, e.g. like this:

static_assert(sizeof(void*) > 4, "This code does not work in 32 bits");
于 2014-01-17T10:47:37.587 回答
1

astatic_assert在编译时assert评估,an 在运行时评估。

于 2014-01-17T10:41:57.360 回答
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");
于 2014-01-17T10:44:52.760 回答