If you do work in C/C++, you're almost certainly familiar with the assert macro and asserts in general. It's unfortunate, though, because although the standard library gives you assert simply by including a simple header, what it provides you with is almost completely worthless. What you get is a macro which changes its definition based on whether NDEBUG is specified. In debug builds, it checks the condition and provides some kind of notification (including debugger notification) if the condition is not satisfied. In release builds, it does absolutely nothing. That's great, until you start writing sizable software and realize just how idiotic this is.
There's a lot of problems with this arrangement. First of all, whether or not asserts are enabled has probably been linked to several other settings as a result of using NDEBUG:
* Is optimization enabled?
* Are symbols available?
* What versions of other libraries are being linked?
* What floating point model is in use?
* Is RTTI enabled?
* Are exceptions enabled?
These are all totally irrelevant, and in fact there's a lot of cases where you for god's sake want asserts to be enabled regardless of what those values are. (This gets to be real fun around the time the optimizer starts breaking your code.) Asserts should be on their own flag for enabled or not, completely separate of everything else. That way, you can have optimized (ie, playable speed) release builds that won't explode with zero indication of what the hell happened. Or, you can check that basic assumptions of your math are correct regardless of what floating point model is currently set.
Then there's the matter of what exactly should happen to an assert in various configurations. There are a lot of situations where you don't actually want to remove asserts, but actually convert them to exceptions or longjmps (I know, I know) or something. There's any number of reasons for this, but basically it boils down to the fact that most assert conditions are ridiculously cheap to check, and no software is perfect. If you've used asserts liberally -- which you should -- then this provides sort of a last ditch protection and debugging mechanism you can use when your customer comes to you with a crash and no information apart from a stack dump.
Different asserts will generally vary in importance, too. It's not unusual to verify on data errors in a console game, even though that'd be really poor form in a PC game. You might want to treat code and data errors differently, log them to different streams, ignore them in some cases, etc. It becomes useful to have different classes of asserts which are linked into the logging and error handling subsystems in different ways. Depending on the type of build, it can also be useful to control each category of assert with a separate define. In short, you need your own asserts. It's not just that the library assert is badly done. No library assert will ever be adequate, because it will either be too simple to be useful or too complex to be usable. Any sizable code base should have its own custom assert implementation that is tailored to the needs of that codebase and its engineers.
Luckily, writing an assert implementation is really easy. You can pretty much just start by copying the library assert and then making tweaks to it from there. (It is kind of important to start with the library implementation, though. It's written funny because of some important subtleties that you're unlikely to realize on your own.) The basic idea is that you have an assert macro which is going to call an assert function when enabled. You'll probably throw in some niceties with __FILE__ and other similar preprocessor directives. The actual assert function is usually a free function that ties into a global logging system and does the most appropriate thing. (Logging is one of those things that looks more and more attractive as a straight up honest to god global as days go by.) After that it's just patching in whatever features you want from your assert, most of which take trivial amounts of effort to actually implement.