Hi,
I'm debating the pros and cons of embedding preprocessor conditional directives *within* expressions. Considering that the directive must begin on a (new) line, this forces the expression to span lines -- often at unnatural places.
For example:
foo = bar // not yet complete! #ifdef OPTION + baz // have to include this, as well! #endif ; // trailing statement terminator
Granted, I can cheat a little (in some cases) and hope the optimizer is smart enough for "obvious" optimizations:
foo = bar + (OPTION * baz);
but this forces OPTION to always be defined *and* means it must always have the value 0 or 1 (in this example). Failing to observe this contract causes hidden bugs.
OK, in the header defining OPTION you *could*:
#ifndef OPTION # error "Hey, you forgot to define OPTION!" #endif
#if (OPTION != 0) && (OPTION != 1) # error "Sorry, OPTION must have a value of '0' or '1'." #endif
But, there are cases where you actually want to include the "string" in your source -- or not -- based on that OPTION. E.g., an optional trailing "default" parameter override in a C++ method invocation.
The point of the question is the relative merit of deliberately breaking source lines to support conditionals.
E.g., the other way of doing this is to specify the variations of that source line in different branches of that conditional:
#ifdef OPTION foo = bar + baz; #else // OPTION foo = bar; #endif
But, this is prone to foul-up as it requires the developer to carefully craft the two (or more!) different variants of the statement. Also, it forces the reader to examine each statement and notice the differences therein (e.g., do the diff(1) in your head -- hopefully without injecting any errors in the process!)
What do other folks do in these cases?