What is the difference between assert and static_assert?

C++Assert

C++ Problem Overview


I know that static_assert makes assertions at compile time, and assert - at run time, but what is the difference in practice? As far as I understand, deep down they are pieces of code, like

if (condition == false) exit();
  • Can someone give me an example of where only static_assert will work, or only assert?
  • Do they do anything a simple if statement can't do?
  • Is it bad practice to use them?

C++ Solutions


Solution 1 - C++

You ask three questions, so I will try to answer each of them.

  • Can someone give me an example of where only static_assert will work, or only assert?

static_assert is good for testing logic in your code at compilation time. assert is good for checking a case during run-time that you expect should always have one result, but perhaps could somehow produce an unexpected result under unanticipated circumstances. For example, you should only use assert for determining if a pointer passed into a method is null when it seems like that should never occur. static_assert would not catch that.

  • Do they do anything a simple if statement can't do?

assert can be used to break program execution, so you could use an if, an appropriate error message, and then halt program execution to get a similar effect, but assert is a bit simpler for that case. static_assert is of course only valid for compilation problem detection while an if must be programmatically valid and can't evaluate the same expectations at compile-time. (An if can be used to spit out an error message at run-time, however.)

  • Is it bad practice to use them?

Not at all!

Solution 2 - C++

static_assert is meant to make compilation fail with the specified message, while traditional assert is meant to end the execution of your program.

Solution 3 - C++

OK, I'll bite:

  • Only static_assert works if you want compilation to stop unsuccessfully if a static condition is violated: static_assert(sizeof(void*) != 3, "Wrong machine word size");* Only dynamic assertions can catch dynamic conditions: assert(argc == 1);

  • Simple if statements have to be valid and compilable; static assertions cause compilation failures.

  • No.

*) A practical example might be to prevent the abuse of generic template constructions, such as int x; std::move<int&&>(x).

Solution 4 - C++

> Is it bad practice to use them?

If abused, yes, particularly assert.

One abuse is depending on those assert statements to be active. You should never depend on assert to do anything because the code can be compiled with NDEBUG defined and then assert does nothing. Production code is oftentimes compiled with NDEBUG defined to ensure that those assert statements disappear.

Unless you are writing a one-off program that won't live for more than a day or two, you shouldn't use to validate user input. Users don't care where the code failed, and the message that is printed looks like a foreign language to many users. It doesn't tell the user how to fix the error. It's also very unforgiving, by design. The message issued in response to a user input error should be a message that tells the user how to fix the problem. The best action after the message is to offer the user a way to fix the error. If that can't be done, and if the only viable response is to end the program, the program should terminate cleanly. By design, assert does not result in a clean shutdown. It calls abort() rather than exit().

One consequence of abort() on many machines is to produce a core dump. A core dump is a great error message for a programmer. With a core dump, a programmer can use the debugger to see what went wrong in great detail. A downside of abort() is that things aren't cleaned up. Abort "terminates the program without executing destructors for objects of automatic or static storage duration and without calling the functions passed to atexit()."

Bottom line: It's okay (and good) to use assert to test for programming errors, but only in a non-production setting. Use something else to test for user errors.

Solution 5 - C++

static_assert is a compiler directive. It allows you to check type information at compile time. It will cause a compilation failure and produce an error message that in most IDE's be caught and displayed in the IDE's error window.

static_assert(sizeof(int) == 4,"int should be 4 bytes");

assert is for runtime, you can check a variable's value. If the assertion fails then the assertion will trigger. This will cause an error message box that will appear at runtime in some Operating systems (assert implementation dependent)

assert(("mypointer  should never be null!", mypointer != nullptr));

Solution 6 - C++

It should be mentioned that it is important to find out about bugs as early as possible. A programmer wants to know when something first goes wrong, instead of the hundreds of problems caused by the original problem. If the code calculates a bad value and then uses it in subsequent calculations, all those calculations are wrong. Finding the earlies cause of the problem prevents the programmer from having to trace the bug back in time.

This is true for both run-time and compilation. Assert helps with this for run-time and static_assert helps with this for compilation. An example of where static_assert is useful for compile time checking to make sure the version of some header is perhaps equal to the version the rest of the code requires or was tested against. If the static_assert tells you the header version changed, it is much more useful than trying to figure out why you have all these compilation errors triggered by the changed header. It detects the problem as early as possible in the compilation process.

Another use for static_assert is to check whether the compilation was done with the right compiler switches. Microsoft's compilers, for example, use /J to signal that char be unsigned 8-bit value rather than signed. If the code requires it, it can be checked at compile time.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionOleksiyView Question on Stackoverflow
Solution 1 - C++pattivacekView Answer on Stackoverflow
Solution 2 - C++Nicola MusattiView Answer on Stackoverflow
Solution 3 - C++Kerrek SBView Answer on Stackoverflow
Solution 4 - C++David HammenView Answer on Stackoverflow
Solution 5 - C++Yochai TimmerView Answer on Stackoverflow
Solution 6 - C++Paul ToppingView Answer on Stackoverflow