Abstraction Chop

See also Binary Chop.

Regardless of the method (macros, inline code, or Query Methods), an Abstraction Chop is a technique for separating conditional logic from the associated code blocks, allowing you to test if The Problem is in the conditions themselves, or in the code blocks.


In some environments, I've created macros that let me replace complicated conditionals with known good (syntactically) template equivalents, but leaving the inside of the blocks unchanged. For example:

Replace:

/* pre-example */ if (a really complicated expression) { /* some code */ } else { /* some more code */ } /* post-example */

with:

/* pre-example */ if (testA) { /* some code */ } else { /* some more code */ } /* post-example */

Playing games like this helps to discover whether problems are in the conditional logic or inside the blocks.


I use a very similar (but apparently simpler) approach. Given Tom's first example code, I might temporarily rewrite it as:

/* pre-example */ if ( true || a really complicated expression) { /* some code */ } else { /* some more code */ } /* post-example */

If I wanted the else clause to execute, of course I'd use "if( false && ...". This kind of stuff works best if you have really fast turn around times. -- Curtis Bartley

If compiling is a problem, using an online debugger set the program counter to the appropriate block when stepping through, thus sidestepping the conditional expression. If your conditional expression has side effects, you will naturally have to manually recreate the side effects. Check first that you aren't inlining too aggressively.


Tom's approach sounds like Kent Beck's Query Method done with macros. The advantage of Query Method really comes out if you follow a test-driven approach. --Kiel Hodges

You can use Query Method in C++ and Java. I don't see where creating your own control structures comes in. A Query Method is essentially a method which returns a boolean for use in other control structures; it's not, say, a method which accepts a block and executes it conditionally somehow. -- Dave Harris


A vaguely related coding trick I've sometimes used in C/C++ is...

static bool bFlag = false; // set 'true' in debugger if (bFlag) // interesting stuff here...

Then I can "comment/uncomment" code during runtime

(even in "fascist" development frameworks ;-) by setting a breakpoint and changing the static value by hand.


Microsoft's Visual C++ has that pattern in its memory allocator. There's a variable called _crtBreakAlloc, and a counter called _lRequestCurr which is incremented on every call to malloc(). When the two are equal, the allocator breaks into the debugger. You have to use the debugger to set the value of crtBreakAlloc you want it to break on. -- Dave Harris


I encountered a case where I made enough memory allocations to cause _lRequestCurr to wrap around to -1; since _crtBreakAlloc is -1 by default my program halted (it was running in the debugger at the time). So if you see an odd debug break at

if (lRequest_ == _crtBreakAlloc) _CrtDebugBreak();

then this could be why.


See original on c2.com