
Assert() in the hands of bad coders - deafcalculus
http://blog.erratasec.com/2017/03/assert-in-hands-of-bad-coders.html
======
michaelt

      Normally, asserts are only compiled into debug versions
      of the code, and removed for release versions.
    

I know a lot of languages default to this, and it always seemed like a bad
decision to me. The performance benefits of most checks are trivial compared
to the major downside of not testing the exact code you release.

Several times I've had to track down bugs that have been very difficult to
find, as they were 'fixed' by side effects of assert statements and hence
didn't show up in debug builds.

If a check really can't be performed in the release version for performance
reasons, just separate it out into a unit test.

~~~
jasode
_> bugs that have been very difficult to find, as they were 'fixed' by side
effects of assert statements and hence didn't show up in debug builds._

In those cases, the assert() was used incorrectly. However, that's not a
reason to include the assert code in release builds.

In a similar way, source code will often have troubleshooting code such as:

    
    
      #if _DEBUG    // or #ifndef NDEBUG
        std::cerr << "inspect size: " << invoices.size() << std::endl;
        // more debugging-related code ...
      #endif
    

Just because some programmers mistakenly put unintended side-effects in
between the #if_DEBUG/#endif doesn't mean we _want_ that code in the release
builds. The purpose of assert() and _DEBUG is to _not include them in release
builds_.

~~~
dllthomas
Your troubleshooting code flushed stderr. That's a side effect, and
occasionally it will matter.

~~~
wruza
stderr is usually not buffered anyway.

~~~
dllthomas
Usually.

------
wruza
The rule is simple: you never assert() things that can happen, you assert ones
that _can not_.

------
onion2k
_This use of assert is silly. The code should look like this:_

In examples 2, 3 and 4 the author explains what's wrong with the code and why
it's a bad use of assert(). In example 1 though it's just called silly. What's
wrong with that one?

~~~
BoorishBears
The style used doesn't make sense, and defeats the usefulness of an assert
error message.

You can read an asset in the form

    
    
        I assert that _ will never be true
    

The style shown is saying

    
    
       I assert that false will never be true
    

And the message for the assert failing will be in a similar format

~~~
unwind
I think you meant "... will never be false", that's what makes the
assert(false) so silly.

I feel that some programmers don't understand the actual semantic meaning of
the word "assert", they just use it as an opaque key word meaning "check
this", or something.

To me, it should be possible to read an assert almost like English, i.e.

    
    
        assert(handle != INVALID_HANDLE);
    

can be read like "assert that the handle isn't invalid", i.e. is valid. Hm.
I'm not stating this very clearly, sorry.

~~~
BoorishBears
Indeed I meant false (actually "will always be true" would probably have been
easier to understand as well)

------
xutopia
The nuance of calling people names is lost on the author. Bad code can be
written by great coders. It happens to the best of us. No need to insult
people to improve code.

~~~
GoToRO
Do you insult a red car when you call it "a red car"? do you insult a bad
programmer when you call him "a bad programmer". It seems that you can't
handle reality.

Knowing where you are will help you progress. Believing that you are good
while being bad has the only effect that you will not do anything to improve
so you will stay bad. Is that what you want?

~~~
luckroy
"Red" is an objective attribute; "bad" is a subjective one.

I agree that self-evaluation and recognition of inferior practices will help
one progress, but the article would be more effective if the author was less
condemning.

