On Tue, Aug 21, 2012 at 4:47 PM, Alex Rousskov <rouss...@measurement-factory.com> wrote: > On 08/21/2012 12:19 AM, Kinkie wrote: >>> .h file: >>> > #if OPTIONAL_FEATURE >>> > extern void someFunction(); >>> > #else >>> > // #define someFunction() // NOP >>> > // or: >>> > // static inline someFunction() {/* NOP */} >>> > >>> > #endif >>> > >>> > .cc file: >>> > #if OPTIONAL_FEATURE >>> > void someFunction() >>> > { >>> > //code >>> > } >>> > #endif >>> > >>> > client code: >>> > someFunction(arg); >> If any, I'd go for static inline (or just inline, after all the >> namespace is already polluted). >> Is the cost of the extra function call worth the decreased readibility? > > No statics or #defines in headers unless really necessary, please. > > Use inline. Inline has the same effect on the namespace as static but > the call to an [empty] inline function is more likely to be removed by > the compiler. If done right, there will be no runtime cost in most cases. > > Please be careful about function arguments though. They or related > conversion operators are sometimes unavailable outside of > OPTIONAL_FEATURE protection. > > You may have to create a shadow hierarchy of types and names to use this > approach in some cases (some recent Squid code does things like that; > see src/ipc/AtomicWord.h, for example). > > This NullObject-like approach works best for commonly used things. If we > are talking about a single obscure function call which requires > #inclusion of a complex header, then it may be best to leave it (and its > #include) inside #ifdef guards to minimize complications.
I'm thinkin about applying some judgement and the Pareto principle: if we can reduce 80% of #if USE_STUFF we have got a good result already. For instance: in protos.h #if USE_WCCP void wccpInit(void); #endif in wccp.cc #if USE_WCCP // stuff void wccpInit(void) { // code } // stuff #endif in main.cc: #if USE_WCCP wccpInit(); #endif This is a very simple example, and also a very typical one. I'd like to turn it into: wccp.h: /** initialize wccp * \note it's a NOP unless USE_WCCP is defined */ void wccpInit(void); wccp.cc: #if USE_WCCP // stuff void wccpInit(void) { // code } // stuff #else void wccpint(void) {} #endif main.cc: wccpinit(); Alternatively (less readability and less runtime overhead), wccp.h: #if USE_WCCP void wccpInit(void); #else inline void wccpInit(void) {} #endif //everything else as previous example // but in this case, where do we put doxyigen-docs? Before the #if USE_WCCP? For more complex stuff, I'd live as is; the tradeoff of readability vs. problems arising from code duplication is this case riskier. -- /kinkie