Question

example of using assertions during debugging:

char* append(char* pStr, const char* pAddStr)
{
    // Verify non-null pointers

    assert(pStr != nullptr);
    assert(pAddStr != nullptr);

    // Code to append pAddStr to pStr...
}

Calling the append() function with a null pointer argument in a simple program produced the following diagnostic message on my machine:

Assertion failed: pStr != nullptr, file c:\beginning visual c++ 2010\examples visual studio project files\tryassertion\tryassertion\tryassertion.cpp, line 10

I would like to know if assertions are neccesary. What is the point of using them if i can use if-else expressions to output my own error messages?

Was it helpful?

Solution

An assertion is a conditional check; it's just a macro that's something like this (simplified):

#define assert(b) if (!(b)) { std::cerr << ...; exit(1); }

I can think of two advantages:

  1. When you compile in release mode (i.e. not in debug mode), then all the asserts will compile away to nothing, so you will incur no runtime overhead.
  2. assert is an idiom; other programmers know to look for them, and they're also distinct from "normal" control flow.

OTHER TIPS

assertions are used to ensure that certain basic assumptions are met. Basically you put in an assertation in every case which "couldnt possibly happen", most commonly assertions how the API has to be used e.g. preconditions and postconditions (like your example, which contains asserts which check the correct usage of your append function). For other errors, which are known to occur during runtime and which cannot be prevented beforehand (e.g. file-not-found or insufficient-permissions kind of errors), you will have to write error handling code.

Assertions are not included in release compilations, so they can only be used to catch critical programming errors, which will already occur in debug-mode test runs.

You should use assertions when the only case in which they are violated is an error in the program logic. You use normal if-then-else conditionals for things that may indeed happen because of input or external possible conditions (i.e. a file is missing).

When you know for sure that the program logic is faulty there is not really much sense in trying to continue execution... your program is working differently from what you think (because otherwise the assertion wouldn't have been triggered) and therefore the best option is just to yell what the problem is and die immediately.

Often assertion are removed when the code is compiled in "release" mode even if however it may make sense to keep them in place if the program logic is very complex and if continuing execution generating bad output is going to create bigger problems than stopping execution.

Note that a "trap" that sometimes novice programmers fall into with assertion is that when the assertion code is removed for release mode the expression inside the assert is not evaluated any more, and therefore if you program depends on side effects of that expression then you're going to be in trouble... for example:

...
assert(insert_record(db, data) == DB_OK);  // <== this is bad
...

when assertion are defined away the insertion will not happen at all, leaving you with a program that doesn't work in release mode and that works instead when you try to debug the problem.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top