Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I am a big fan of writing assert checks in C++ code as a way to catch cases during development that cannot possibly happen but do happen because of logic bugs in my program. This is a good practice in general.

However, I've noticed that some functions I write (which are part of a complex class) have 5+ asserts which feels like it could potentially be a bad programming practice, in terms of readability and maintainability. I think it's still great, as each one requires me to think about pre- and post-conditions of functions and they really do help catch bugs. However, I just wanted to put this out there to ask if there is a better paradigms for catching logic errors in cases when a large number of checks is necessary.

Emacs comment: Since Emacs is my IDE of choice, I have it slightly gray out the assert statements which helps reduce the feeling of clutter that they can provide. Here's what I add to my .emacs file:

; gray out the "assert(...)" wrapper
(add-hook 'c-mode-common-hook
  (lambda () (font-lock-add-keywords nil
    '(("\\<\\(assert\(.*\);\\)" 1 '(:foreground "#444444") t)))))

; gray out the stuff inside parenthesis with a slightly lighter color
(add-hook 'c-mode-common-hook
  (lambda () (font-lock-add-keywords nil
    '(("\\<assert\\(\(.*\);\\)" 1 '(:foreground "#666666") t)))))
share|improve this question
2  
I must admit that this is a question that has crossed my mind now and again. Interested to hear others' opinions on this. –  Diego Deberdt Jun 27 '11 at 12:01

5 Answers 5

up vote 29 down vote accepted

I've seen hundreds of bugs that would have been solved faster if someone had written more asserts, and not a single one that would have been solved quicker by writing fewer.

[C]ould [too many asserts] potentially be a bad programming practice, in terms of readability and maintainability[?]

Readability could be a problem, perhaps - although it's been my experience that people who write good asserts also write readable code. And it never bothers me to see the beginning of a function start with a block of asserts to verify that the arguments aren't garbage - just put a blank line after it.

Also in my experience, maintainability is always improved by asserts, just as it is by unit tests. Asserts provide a sanity check that code is being used the way it was intended to be used.

share|improve this answer
1  
Good answer. I also added a description to the question of how I improve readability with Emacs. –  Lex Jun 27 '11 at 12:25
2  
"it's been my experience that people who write good asserts also write readable code" << excellent point. Making code readable is as up to the individual programmer as it is the techniques he or she is and isn't allowed to use. I've seen good techniques become unreadable in the wrong hands, and even what most would consider bad techniques become perfectly clear, even elegant, by the proper use of abstraction and commenting. –  Greg Jackson Jun 27 '11 at 19:24

Too few assertions: good luck changing that code riddled with hidden assumptions.

Too many assertions: can lead to readability problems and potentially code smell - is the class, function, API designed right when it has so many assumptions placed in assert statements?

There could be also assertions that do not really check anything or check things like compiler settings in each function :/

Aim for the sweet spot, but no less (as someone else already said, "more" of assertions is less harmful than having too few or god help us - none).

share|improve this answer

I find that over time I write fewer asserts because many of them amount to "is the compiler working" and "is the library working". Once you start thinking about what exactly you're testing I suspect you'll write fewer asserts.

For example, a method that (say) adds something to a collection shouldn't need to assert that the collection exists - that's generally either a precondition of the class that owns the message or it's a fatal error that should make it back to the user. So check it once, very early on, then assume it.

Assertions to me are a debugging tool, and I'll generally use them in two ways: finding a bug at my desk (and they don't get checked in. Well, perhaps the one key one might); and finding a bug on the customer's desk (and they do get checked in). Both times I'm using assertions mostly to generate a stack trace after forcing an exception as early as possible. Be aware that assertions used this way can easily lead to heisenbugs - the bug may well never occur in the debug build that has assertions enabled.

share|improve this answer

It would be awesome if you could write an Assert function that took only a reference to a boolean CONST method, in this way you are certain that your asserts do not have side effects by ensuring that a boolean const method is used to test the assert

it would draw a bit from readability, specially since i don't think you can't annotate a lambda (in c++0x) to be a const to some class, meaning you can't use lambdas for that

overkill if you ask me, but if i would start seeing a certain level of polution due to asserts i would be wary of two things:

  • making sure no side-effects are happening in the assert (provided by a construct as explained above)
  • performance during development testing; this can be addressed by adding levels (like logging) to the assert facility; so you can disable some asserts from a development build in order to improve performance
share|improve this answer
    
Holy crap you like the word "certain" and its derivations. I count 8 uses. –  Casey Patton Jun 27 '11 at 19:11
    
yes, sorry i tend to clique on words way too much - fixed, thanks –  lurscher Jun 27 '11 at 19:16

I've written in C# much more than I did in C++, but the two languages are not terribly far apart. In .Net I do use Asserts for conditions that should not happen, but I also often throw exceptions when there is no way to continue. The VS2010 debugger shows me plenty of good info on an exception, no matter how optimized the Release build is. It is also a good idea to add unit tests if you can. Sometimes logging is also a good thing to have as a debugging aid.

So, can there be too many asserts? Yes. Choosing between Abort/Ignore/Continue 15 times in one minute gets annoying. An exception gets thrown only once. It is hard to quantify the point at which there are too many asserts, but if your assertions fulfill the role of assertions, exceptions, unit tests and logging, then something is wrong.

I would reserve assertions for the scenarios that should not happen. You may over-assert initially, because assertions are faster to write, but re-factor the code later - turn some of them into exceptions, some into tests, etc. If you have enough discipline to clean up every TODO comment, then leave a comment next to each one that you plan to rework, and DO NOT FORGET to address the TODO later.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.