Domanda

I am trying to understand the use of static_assert and assert and what the difference is between them, however there are very little sources/explantions about this

here is some code

// 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();
}

comments on redundency will be appreciated(since I am learning "how to c++")

output in 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

I have been trying to find out the different mehtods and uses of it, but as far as I understand it is a runtime check and another "type" of if statement

could someone just clarify the use and explain what each one does and they difference?

È stato utile?

Soluzione

You can think of assertions as sanity checks. You know that some condition should be true unless you've screwed something up, so the assertion should pass. If you have indeed screwed something up, the assertion will fail and you'll be told that something is wrong. It's just there to ensure the validity of your code.

A static_assert can be used when the condition is a constant expression. This basically means that the compiler is able to evaluate the assertion before the program ever actually runs. You will be alerted that a static_assert has failed at compile-time, whereas a normal assert will only fail at run time. In your example, you could have used a static_assert, because the expressions 2+2==4 and 2+2==5 are both constant expressions.

static_asserts are useful for checking compile-time constructs such as template parameters. For example, you could assert that a given template argument T must be a POD type with something like:

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

Note that you generally only want run-time assertions to be checked during debugging, so you can disable assert by #defineing NDEBUG.

Altri suggerimenti

assert() is a macro whose expansion depends on whether macro NDEBUG is defined. If so, assert() doesn't expand to anything - it's a no-op. When NDEBUG is not defined, assert(x) expands into a runtime check, something like this:

if (!x) cause_runtime_to_abort()

It is common to define NDEBUG in "release" builds and leave it undefined in "debug" builds. That way, assert()s are only executed in debug code and do not make it into release code at all. You normally use assert() to check things which should always be true - a function's preconditions and postconditions or a class's invariants, for example. A failed assert(x) should mean "the programmer thought that x holds, but a bug somewhere in the code (or in their reasoning) made that untrue."


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");

a static_assert is evaluated at compile time, an assert is evaluated an runtime.

I doubt you cannot find any sources for this, but I’ll nevertheless give some explanation.

assert is for runtime checks which should never ever fail. If they fail, the program will terminate ungracefully. You can disable assertions for a release build by specifying a compile time flag. As assertions should never fail (they are assertions after all), in a working program, that should not make any difference. However, the expressions inside an assert must not have side effects, because there is no guarantee that they are executed. Example:

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 is new and can be used to perform compile time checks. They will produce a compiler error when they fail and block the program from compiling:

static_assert(sizeof(char) == 1, "Compiler violates the standard");
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top