When to assert?

Started by
4 comments, last by Extrarius 19 years, 6 months ago
Hi, I want to learn how to debug better and I was reading about assert. So does anybody know when to use this. For example im programming C++ .net, win32 app. assert(m_hInst = GetModuleHandle(NULL)); would this be a case to use it. I know it should never error, but thats what I read about using assert, use it on things that should always work. Or should I just use an if statment. m_hInst = GetModuleHandle(NULL); if(m_hInst == NULL){ return error; } Is this what assert is used for or is it for things that are simple like assert(dayInMonth <= 31) or something?
Advertisement
Assert is used to make sure you haven't screwed up. If something should never be able to happen, you assert that that is the case. If a function takes a pointer and that pointer should never be null, you would assert(pointer != NULL);. if a number should always be between 1 and 10, you would assert(number >= 1 && number <= 10);.

Assert is actually a macro, and will become nothing if NDEBUG is defined, which you would define when you've killed all your bugs (as if that will ever happen) and are releasing your program to the public. Therefore, you do NOT want a statement like assert(m_hInst = GetModuleHandle(NULL));, because m_hInst will never be set to anything in the final version of your program, it would crash, and your customers will chase you angrily with torches and pitchforks.
Chess is played by three people. Two people play the game; the third provides moral support for the pawns. The object of the game is to kill your opponent by flinging captured pieces at his head. Since the only piece that can be killed is a pawn, the two armies agree to meet in a pawn-infested area (or even a pawn shop) and kill as many pawns as possible in the crossfire. If the game goes on for an hour, one player may legally attempt to gouge out the other player's eyes with his King.
Indeed you should use assert on things that HAVE to be true for the rest of the function to work, or when returning an error is not an option. Returning an error code can sometimes hide a more sinister problem further up, and you may never be aware of it without asserts, unless you perform analysis on every functions return value.

I sometimes do both, like

if ((shouldAlwaysBeTrue) == FALSE)
{
ASSERT(FALSE);
return FALSE;
}

so that if it fails, it will still work, but it brings the problem to my attention much more obviously than performing a check on the return value. If you are using Win32, look into verify() as well and make sure you know the difference betweeen that and assert (in your first example you would need to use verify otherwise the whole assert() is ignored in release mode!)

My 2 cents anyway!
http://www.eyt.ca/blog/item/13/

I'd also like to point out that C++ has a std::logic_error exception class.
Free Mac Mini (I know, I'm a tool)
what smart_idiot mentioned should be reiterated.

In a debug build the code:
assert(m_hInst = GetModuleHandle(NULL));


In effect is:
assert(m_hInst = GetModuleHandle(NULL));


In a release build that same code is:
// nothing.



Alright, now that that is out of the way.

I like to assert on things that are true. (like this != NULL, or bvar == true after I've just did a if bvar != false .. things of that nature. Paranoia? Yes, but I've had some of the damdest things happen before ;)

Note that you should not use assert to catch conditions that are expected. (such as a parameter being null. Rather, you should assert but you shold also if that condition as well. I like to assert in the if handler) Mostly for reuse issues.

Fwiw.
ASSERT everywhere. That way, if you forgot to properly handle an error, you'll get an ASSERT message telling you so.

Also, in MSVC it would be a good idea to make the macro something like:

#ifndef NDEBUG
#define assert(b,msg) _ASSERT((b), (msg), __FILE__, __LINE__, __FUNCTION__)
#else
#define assert(b,msg) __assume(b)
#endif

which will mean that in release mode, the optimizer will assume the condition is always true, and so it will make optimizations to that effect.
"Walk not the trodden path, for it has borne it's burden." -John, Flying Monk

This topic is closed to new replies.

Advertisement