Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does assert(0) mean?

I had a question like this on one of my exams and I'm still not too sure how to answer it. I understand that assertions are ways to test your program, however I'm not too sure what assert(0) is checking. Is this a trick question? It will always fail, but I don't understand why. What is it checking?

Any explanation would be great, thanks.

like image 270
Smith Western Avatar asked Dec 12 '15 05:12

Smith Western


People also ask

What is assert 0 Python?

The assert keyword lets you test if a condition in your code returns True, if not, the program will raise an AssertionError.

How does assert () work?

The assert() function tests the condition parameter. If it is false, it prints a message to standard error, using the string parameter to describe the failed condition. It then sets the variable _assert_exit to one and executes the exit statement. The exit statement jumps to the END rule.

What does assert mean C?

In the C Programming Language, assert is a macro that is designed to be used like a function. It checks the value of an expression that we expect to be true under normal circumstances. If expression is a nonzero value, the assert macro does nothing.

What does assert false mean in C++?

An assert is a preprocessor macro that is used to evaluate a conditional expression. If the conditional expression evaluates false, then the program is terminated after displaying the error message.


3 Answers

The C++ standard defers the definition of assert to the C standard.

C99 §7.2/2:

The assert macro puts diagnostic tests into programs; it expands to a void expression. When it is executed, if expression (which shall have a scalar type) is false (that is, compares equal to 0), the assert macro writes information about the particular call that failed (including the text of the argument, the name of the source file, the source line number, and the name of the enclosing function — the latter are respectively the values of the preprocessing macros __FILE__ and __LINE__ and of the identifier __func__) on the standard error file in an implementation-defined format. It then calls the abort function.


In assert(0) the 0 is interpreted as false, so this assertion will always fail, or fire, when assertion checking is on.

Thus it asserts that

“The execution will never reach this point.”

In practice it can be difficult to make compilers shut up about the execution reaching or not reaching a given point. Often the compiler will first complain about the execution possibly reaching the end of a function without returning a value. Adding an assert(0) there should ideally solve that issue, but then the compiler may complain about the assert, or not recognize that it says you're already well aware of what it tries to warn about.

One (1)possible measure then is to also throw an exception at that point:

auto foo( int x )     -> int {     if( x == 1 ) { return 42; }     assert( 0 ); throw 0;       // Should never get here! } 

Of course that double-whammy can be defined as a higher level macro. Regarding the exception type you may want to keep it as not a std::exception, because this is not an exception intended to be caught by an ordinary catch anywhere. Or, if you trust the standard exception hierarchy (it doesn't make sense to me, but) you can use a std::logic_error.


To turn off assert assertion checking you can define the symbol NDEBUG before including <assert.h>.

This header has special support so that you can include it multiple times, with or without NDEBUG defined.

C++11 §17.6.2.2/2:

A translation unit may include library headers in any order (Clause 2). Each may be included more than once, with no effect different from being included exactly once, except that the effect of including either <cassert> or <assert.h> depends each time on the lexically current definition of NDEBUG.

A reasonable definition of the double-whammy discussed above can likewise depend on NDEBUG with no include guard, e.g.

File assert_should_never_get_here.hpp
#include <stdexcept>        // std::logic_error #include <assert.h>  #undef ASSERT_SHOULD_NEVER_GET_HERE #ifdef NDEBUG #   define ASSERT_SHOULD_NEVER_GET_HERE() \         throw std::logic_error( "Reached a supposed unreachable point" ) #else #   define ASSERT_SHOULD_NEVER_GET_HERE() \         do{ \             assert( "Reached a supposed unreachable point" && 0 ); \             throw 0; \         } while( 0 ) #endif 

Disclaimer: While I coded that up a number of times in the early 2000s, I cooked up the code above just for this answer, and while I did test it with g++ it may not necessarily be perfect.


(1) See Basile Starynkevitch's answer for discussion of another possibility, the g++-specific intrinsic __builtin_unreachable.

like image 149
Cheers and hth. - Alf Avatar answered Sep 28 '22 05:09

Cheers and hth. - Alf


It will always fail. That's pretty much it. It will fail always for the same reason that "assert(x == 5)" will succeed whenever x = 5.

If you're asking for an application then you would put it in code blocks that really shouldn't happen.

switch(suit) {
  case CLUB:
  case DIAMOND:
  case HEART:
  case SPADE:
  // ...
  default:
    assert(0);
 }
like image 40
djechlin Avatar answered Sep 28 '22 06:09

djechlin


Yes, it will always fail.

assert(0) or assert(false) is usually used to mark unreachable code, so that in debug mode a diagnostic message is emitted and the program is aborted when the supposedly unreachable is actually reached, which is a clear signal that the program isn't doing what we think it is.

like image 26
emlai Avatar answered Sep 28 '22 07:09

emlai