tags:

views:

589

answers:

8

How are assertions done in c++? Example code is appreciated.

+5  A: 

Assertion are boolean expressions which should typically always be true.

They are used to ensure what you expected is also what happens.

void some_function(int age)
{
     assert(age > 0);
}

You wrote the function to deal with ages, you also 'know' for sure you're always passing sensible arguments, then you use an assert. It's like saying "I know this can never go wrong, but if it does, I want to know", because, well, everyone makes mistakes.

So it's not to check for sensible user input, if there are scenario's where something can go wrong, don't use an assert. Do real checks and deal with the errors.

Asserts are typically only for debug builds, so don't put code with side effects in asserts.

Pieter
+1  A: 

An assertion is something you add to your program that causes the program to stop immediately if a condition is met, and display an error message. You generally use them for things which you believe can never happen in your code.

Dave Markle
+18  A: 

Asserts are a way of explicitly checking the assumptions that your code makes, which helps you track down lots of bugs by narrowing down what the possible problems could be. They are typically only evaluated in a special "debug" build of your application, so they won't slow down the final release version.

Let's say you wrote a function that took a pointer as an argument. There's a good chance that your code will assume that the pointer is non-NULL, so why not explicitly check that with an assertion? Here's how:

#include <assert.h>

void function(int* pointer_arg)
{
    assert(pointer_arg != NULL);

    ...
}

An important thing to note is that the expressions you assert must never have side effects, since they won't be present in the release build. So never do something like this:

assert(a++ == 5);

Some people also like to add little messages into their assertions to help give them meaning. Since a string always evaulates to true, you could write this:

assert((a == 5) && "a has the wrong value!!");
andygeers
I haven't seen the anding with a string before. Real useful!
David Holm
That sort of trick (or a similar variation) is used all the time in Perl-land, namely, using the example given: a == 5 || die("a has the wrong value"); Hurrah for loose boolean typing.
Matthew Scharley
Another trick along the lines of this string is when validating values in release code, but asserting in debug code. For example, use an if(x>10) check first, and then if the erroneous condition passes, just assert(!"x out of bounds") and then print to a logfile, etc.
Marcin
David Sykes
@David: Usually an assert statement will print the failed condition when it fails, along with file/line info. So what it gives you is a human-readable message along with the actual. Equivalently, you could write your own assert with two parameters: a condition and a message.
Steve Jessop
Thanks, but I don't understand how the string gets printed, if the condition fails the assert will only get a false value
David Sykes
David, your IDE will typically display the expression that failed as part of the error message it displays to you, so if your expression contains a string then that'll pop up
andygeers
I see. assert could utilise the passed expression as a string as well as a boolean. Nice! Thanks
David Sykes
> They are typically only evaluated in a special "debug" build of your application. IMO certain (the low cost) assertions should make it to the release build: see http://stackoverflow.com/questions/620892/how-to-put-assert-in-ship-build-in-c-c/629351#629351
Amit Kumar
A: 

Here is a definition of what an assertion is and here is some sample code. In a nutshell an assertion is a way for a developer to test his (or her) assumptions about the state of the code at any given point. For example, if you were doing the following code:

mypointer->myfunct();

You probably want to assert that mypointer is not NULL because that's your assumption--that mypointer will never be NULL before the call.

Onorio Catenacci
+2  A: 

Assertions are statements allowing you to test any assumptions you might have in your program. This is especially useful to document your program logic (preconditions and postconditions). Assertions that fail usually throw runtime errors, and are signs that something is VERY wrong with your program - your assertion failed because something you assumed to be true was not. The usual reasons are: there is a flaw in your function's logic, or the caller of your function passed you bad data.

+4  A: 

Assertions are used to verify design assumptions, usually in terms of input parameters and return results. For example

// Given customer and product details for a sale, generate an invoice

Invoice ProcessOrder(Customer Cust,Product Prod)
{
  assert(IsValid(Cust));
  assert(IsValid(Prod);
'
'
'
  assert(IsValid(RetInvoice))
   return(RetInvoice);

}

The assert statements aren't required for the code to run, but they check the validity of the input and output. If the input is invalid, there is a bug in the calling function. If the input is valid and output is invalid, there is a bug in this code. See design by contract for more details of this use of asserts.

Edit: As pointed out in other posts, the default implementation of assert is not included in the release run-time. A common practice that many would use, including myself, is to replace it with a version that is included in the release build, but is only called in a diagnostics mode. This enables proper regression testing on release builds with full assertion checking. My version is as follows;

extern  void _my_assert(void *, void *, unsigned);

#define myassert(exp)                               \
{                                                   \
    if (InDiagnostics)                    \
     if ( !(exp) )                               \
      _my_assert(#exp, __FILE__, __LINE__); \
}                                                   \

There is a small runtime overhead in this technique, but it makes tracking any bugs that have made it into the field much easier.

Shane MacLaughlin
+2  A: 

Use assertions to check for "can't happen" situations.

Typical usage: check against invalid/impossible arguments at the top of a function.

Seldom seen, but still useful: loop invariants and postconditions.

mfx
+1  A: 

This doesn't address the assert facility which has come down to us from early C days, but you should also be aware of Boost StaticAssert functionality, in the event that your projects can use Boost.

The standard C/C++ assert works during runtime. The Boost StaticAssert facility enables you to make some classes of assertions at compile time, catching logic errors and the like even earlier.

Don Wakefield