Do you ship Debug or Release? - DAB Offensive Programming

On my post STOP() Happens Geoff posted an interesting link of DAB wrote on “Offensive Programming”.

An offensive routine is different. It should have a tightly defined specification of what it does and it should assume that the input parameters are correct and valid (this eliminates flab and rarely entered code-lines from the library routine). However a properly offensive routine should not just assume it is called properly but also insist. The ASSERT clause allows just this…

If you scan the ABC libraries you will find asserts used liberally (they are free when debug is off). They are used to check references aren’t null, parameters are in range, boundary conditions are bet, queues contain expected values. In fact just about anywhere we thought ‘this is bound to be true’ we assert it.

I’m not sure “liberally asserting everything” works well with shipping Debug builds. I do that because the Exception window with the Debug DLL Call Stack is so useful. There is also the Capesoft GPF Reporter which requires a Debug build. ASSERT can he hooked so that you could only show it when running “In House” or other criteria e.g. file name AB*.

I was curious how common it was to ship Debug? I allowed an option that maybe you have special “Debug Beta” builds which implies Gold ships as a Release build.

Build type you Ship
  • Debug Build
  • Debug Betas
  • Release Build

0 voters

(moved from the STOP() Happens thread…)

also related to the DAB article cited above, another article by David Bayliss on the ABC File Manager (Clarion Magazine, June 1999. FileManager II – ABC Design) includes the following:

GetField PROCEDURE(KEY K,BYTE Component),*?

This method is used to return an ANY variable corresponding to a given
component of a key. I didn’t want to have to protect the rest of my code
against GetField returning a null so the procedure ASSERTs that the
incoming component will be found. In other words, GetField gracelessly
handles out of range components.

This does illustrate another agenda within ABC: offensive programming.
Defensively I would have coded so that an out of range value returned a
null, which would take two lines of code. Then on the receiving end nulls
would have been handled, presumably in some “see if we can still keep
going” fashion.

There are four calls to GetField in abfile (i.e., this method is relatively
underused). Each would have had to temporarily store the GetField
result, test for the null and do something smart with it. This might have
taken five lines of code each (one for the declaration, one for the extra
assign, two for the null test, one to handle the null case). In total I
would now need 22 lines of code to handle something that should never
happen as opposed to the one line of code used in ABC. Doing that
throughout a heavily integrated file like ABFILE could turn 2000 lines of
code into 40,000 lines of code 95% of which would be rarely executed
and thus minimally tested. QED.

and finally, two months later in Clarion Magazine in August 1999, in the article Propitious Memory Corruption, DAB writes:

In this situation it will Assert, throw up garbage screen displays (if the assertions are ignored), and generally make it clear something is horribly wrong.


So what is better? A system that works 99% of the time and just subtly corrupts your customers data or a system that downs tools and refuses to budge until it is fixed?

Thanks to Dave Harms you can find the articles at:


I always hook assert so the end-users do not see the messages even if the dlls are shipped compiled in debug. Running in development the assert messages show.

1 Like

we always release Release build but we have DebugView support (using OutputDebugString) inside so we can trace what we need

4th option, it depends.
These days I do everything with full debug all the time. But that’s because most programs I write have to do with either processing files from one format to another, or interacting with USB gizmos of some description, and I just don’t care if someone can be bothered to figure it out.
Back in my previous life, when I was developing Clarion apps professionally, we also built everything (~50 .EXEs, ~160 DLLs) with full debug all the time but builds that were deemed good enough to ship to customers had a post-compile process run on them that borked the TSWD debug symbols out of the binary so that you couldn’t debug them. It was quicker to do that than recompile everything all over again.

This was back in C5 days. These days I still use C6, there’s no reason for me to upgrade yet.


Not yet. Lots of USB & HID code though :slight_smile: