mailto: blog -at- heyrick -dot- eu

Navi: Previous entry Display calendar Next entry
Switch to desktop version

FYI! Last read at 08:41 on 2024/04/27.

The many levels of conditional compilation

I have a program that I am writing that contains a variety of debugging instructions to allow specific bits of debug/tracing code to be activated. One thing that all of the bits of code require is the debug() function to write the printf style string provided to DADebug.
In order to make this a little bit smarter, I wanted to simply choose which (if any) debug options I want, and the compiler itself can figure out whether or not the lower level debugging code should also be included.
This isn't difficult. The process is like this:
// Output information on THIS ?
#define DEBUG_THIS 1

// Output information on THAT ?
// #define DEBUG_THAT 1

// Output information on THEOTHER ?
// #define DEBUG_THEOTHER 1

// Determine if debugging support code is required
#define DEBUG 1
#ifndef DEBUG_THIS
 #ifndef DEBUG_THAT
  #ifndef DEBUG_THEOTHER
   #undef DEBUG
  #endif
 #endif
#endif

With this procedure, if any of the DEBUG_* definitions are 'known', then DEBUG will also be. If none are available, then neither will DEBUG be.

My code currently contains eleven such clauses. I was wondering if I should curtail this. I mean, would the compiler max out at 16 nested definitions like OpenWatcom appears to offer? Maybe it tops out at 32 nested #ifdef statements, like the Microsoft compiler, like Delphi. What is the RISC OS compiler's limit?

It didn't take long to devise a test to check 50 levels of nesting. Which worked. I copypasted incrementally to take this up to 1,200 levels of nested conditionals. That worked too.

Now for the mother lode. This, obviously, needs to be done programmatically. So here's some drop-dead-simple code:

f% = OPENOUT("RAM:$.ifdefs")
FOR l% = 1 TO 65536
  n$ = "#ifndef "
  FOR r% = 1 TO RND(10)
    n$ = n$ + CHR$(RND(26)+64)
  NEXT
  BPUT#f%, n$
NEXT
BPUT#f%, "#define OH_MY_GOD 1"
FOR l% = 1 TO 65536
  BPUT#f%, "#endif"
NEXT
CLOSE#f%
OSCLI("SetType RAM:$.ifdefs &FFF")
END

Running that generated a file of a little over 1.4MiB containing a massive, epic to the point of silly laughter, nested #ifndef structure containing a mere 65,536 items, all of which would be uniquely named. Plus the necessary 65,536 #endif statements.

Prepare to suspend belief. My project contains seven C sources and takes about 18 seconds to build all of that in its current state (changing the primary header file causes everything to be rebuilt - this is by design).
Plugging in the epic to the point of silly laughter nested #ifndef structure (which is dealt with seven times, remember) pushes the build time to 31 seconds. That means chundering through all of that rubbish nearly half a million times (65,536 × 7 = 458,752) adds a mere 13 seconds to the build time. Fu.......................kushima.

The picture on the right hand side? A snippet of the many many lines of random gibberish that doesn't faze the compiler one bit.

So, if anybody asks if there is a limit to how many nested #ifdefs that Norcroft / Acorn / ROOL's compiler can handle, just say this "many have set out on that quest, few have returned" and then walk away.

 

 

Your comments:

No comments yet...

Add a comment (v0.11) [help?]
Your name:

 
Your email (optional):

 
Validation:
Please type 28256 backwards.

 
Your comment:

 

Navi: Previous entry Display calendar Next entry
Switch to desktop version

Search:

See the rest of HeyRick :-)