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++ の使い方」を学んでいるため)

コマンドで出力

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を使用できます。これは基本的に、プログラムが実際に実行される前に、コンパイラがアサーションを評価できることを意味します。a がコンパイル時に失敗したことを警告さstatic_assertれますが、通常assertは実行時にのみ失敗します。あなたの例では、式とは両方とも定数式static_assertであるため、 a を使用できました。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()、常に true であるべきものをチェックするために使用します。たとえば、関数の事前条件と事後条件、またはクラスの不変条件などです。失敗assert(x)とは、「プログラマーはそれxが成り立つと考えていたが、コード (またはその推論) のどこかにバグがあり、それが真実ではなかった」ことを意味するはずです。


static_assert()(C++11 で導入された) はキーワードです - eg に似てい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()そうすれば、eg a で呼び出そうとするfloatと、適切なメッセージとともにコンパイル時エラーが発生します。

場合によっては、static_assert()次のように、テンプレート以外でも役立つことがあります。

static_assert(sizeof(void*) > 4, "This code does not work in 32 bits");
于 2014-01-17T10:47:37.587 に答える
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 に答える
1

astatic_assertはコンパイル時に評価され、 anassertは実行時に評価されます。

于 2014-01-17T10:41:57.360 に答える