6

While doing programming i am using assert as well as NULL pointer validation.

But as i know assert will be useful only in DEBUG mode.

My question is suppose i have a internal pointer which i am sure cant be NULL example function returning a pointer(but the pointer is not a member of class) in such cases i can use assert

test* ptr = fun(); // return a pointer of type test
assert(ptr);

//do some operation

or NULL pointer validation

test* ptr = fun(); // return a pointer of type test
assert(ptr);
if (NULL != ptr)
{
    //do some operation
}

Here which code practice is good.As per my understating it will be second one. Because i have faced some situations where the value of ptr returns NULL due to some abnormal cases that we cant even think of.

But do we have any other better options?

Astro - Amit
  • 767
  • 3
  • 15
  • 36
  • Why this question is voted for close? It is a valid question. – Nawaz Jan 11 '13 at 06:52
  • Have you considered not to return null? Would be much easier to write code. I.e. empty arrays/special [null objects](http://en.wikipedia.org/wiki/Null_Object_pattern) and exceptions may significantly limit need of returning null and hence checking for it. – Alexei Levenkov Jan 11 '13 at 06:54
  • @AlexeiLevenkov check second case – Astro - Amit Jan 11 '13 at 06:59
  • Which one? You only show one case of function returning null and you said that this function have contract to never return null but does not respect it. Failing with access denied maybe only marinally worse in this case than failing with custom exception in this case... – Alexei Levenkov Jan 11 '13 at 07:16
  • 1
    If you're in love with `assert()` then do *both* in congruence. `assert(ptr && "Unexpected NULL pointer"); if (ptr) {...}`. Choosing only assert() ignores the reason your asserting in the first place in release builds, and choosing only if (ptr) hides the unexpected you're being pedantic about to begin with in debug builds. – WhozCraig Jan 11 '13 at 07:58
  • See also: [Assert() - what is it good for ?](http://stackoverflow.com/questions/12161998/assert-what-is-it-good-for), [Is using assert() in C++ bad practice?](http://stackoverflow.com/questions/12062365/is-using-assert-in-c-bad-practice) and [design by contract tests by assert or by exception?](http://stackoverflow.com/questions/117171/design-by-contract-tests-by-assert-or-by-exception). – CB Bailey Jan 11 '13 at 08:03
  • @WhozCraig can you tell me why should we give a check to **if (ptr)** ptr is not a bool. So i think better use as ** if ( NULL != ptr)** – Astro - Amit Jan 11 '13 at 08:31
  • 2
    @Amit0440 in C and C++, zero implies `false`, non-zero implies `true` for the purposes of boolean evaluation. Its honestly a matter of taste at this point in the now-many-generations of the C and C++ languages. To each his/her own. – WhozCraig Jan 11 '13 at 08:44

5 Answers5

5

assert says "if this isn't true, there is a logic error in my code". If you are putting in code to handle the fact that pointer might be null then it is the assert call which is redundant. You should add logging and handling to the 'else' case instead. This way your debug build will run in the same way as your release build, even in the null pointer case.

If you really mean assert and you have to abort on a null pointer then enable asserts in your release build or use an alternative release-enabled assert mechanism.

The only reason for a debug-only assert is a check for a logic error that is too expensive to make in release code. Normally a null check for a pointer won't fit into this category.

CB Bailey
  • 755,051
  • 104
  • 632
  • 656
4

The real solution depends on the semantic of the function fun.

If returning NULL is semantically invalid, then I think fun should throw an appropriate exception (such as std::logic_error1) instead of returning NULL, and you could use assert on the call site to ensure that fun is working fine, and if it is not working fine, then abort the program. In this way, the bug in fun doesn't propagate to the rest of the program, as it is caught immediately.

However, if returning NULL from fun is semantically valid, then you should check the return value on the call-site using if and assert is not really needed in this case, because you will use if anyway.

1. Or you could use std::runtime_error or std::domain_error.

Nawaz
  • 353,942
  • 115
  • 666
  • 851
  • some abnormal scenario's can make the value return by **fun** as NULL or memory corruption for that variable.So some other threads also.Which finally means to force me to use second case... – Astro - Amit Jan 11 '13 at 07:06
1

I recommend you to use your own code for assertion. as you said, assert only works in debug mode.

So, if it is working in release mode, it doesn't work.

if you use your own assertion code. you can simply find out what it is wrong.

test* ptr = fun(); // return a pointer of type test
MyOwnAssert(ptr); 

void MyOwnAssert(void* pPointer)
{
   if (NULL == pPointer)
     abort();
}    
VariOov
  • 21
  • 2
  • in above code you checks for NULL not assert and i think above code can be simplified by using MACRO instead of a function – Astro - Amit Jan 11 '13 at 08:35
0

As you mentioned, assert is only during debug, helping the programmer to identify where they went wrong. It has no value in production and so, I prefer using the second method if you have any doubt that the pointer could be NULL.

Kiran
  • 98
  • 7
  • yes i prefer second method....but fun() is ideally can not return NULL. So isn't a extra condition check or always play a safer game with being a safe side :-) – Astro - Amit Jan 11 '13 at 07:00
  • 1
    But if you have the assert in debug you will never test the code path where the pointer is null. This means that if it does happen in production, the subsequent code paths will never have been tested with the pointer being null and the original mistake may be masked by the subsequent code execution. The subsequent code execution may or may not recover from the mistake - this fact can never have been tested. – CB Bailey Jan 11 '13 at 07:53
  • @CharlesBailey i am not suspecting the pointer value to be NULL ever. – Astro - Amit Jan 11 '13 at 08:49
  • @Amit0440: My comment was addressed to KVRNKiran when he said he preferred the second method "if you have any doubt that the pointer could be NULL". – CB Bailey Jan 11 '13 at 09:30
0

What you make of assert is your own choice: you can use is in production if you want.

I'd say, using assert() is better if you want to spot your errors early. Especially if the fact that it's a NULL pointer should not happen.
You could even stick a Google Breakpad in there, so that whenever you hit a NULL pointer you send a report with the full stack at that point.

In cases where a NULL pointer is possible (and sometimes expected...), then I guess the NULL-check is better. But I'd say that at this point your code is wrong somehow, if it must accomodate with NULL pointers being passed around.

Gui13
  • 12,993
  • 17
  • 57
  • 104