On 08/21/2012 09:26 AM, Kinkie wrote:
> On Tue, Aug 21, 2012 at 4:47 PM, Alex Rousskov
> <rousskov_at_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
Either one is OK in this case and seems to have similar readability IMO.
Pick whatever style you prefer and try to be consistent.
However, for this specific example, one should probably use
RegistryRunners instead of making main.cc to be aware of WCCP.
> // but in this case, where do we put doxyigen-docs? Before the #if USE_WCCP?
Ideally, this alternative requires different docs for USE_WCCP and
!USE_WCCP cases (since both are used). If that is not an option, before
#if is probably better than inside #if. I am not an expert on this though.
HTH,
Alex.
Received on Tue Aug 21 2012 - 15:48:55 MDT
This archive was generated by hypermail 2.2.0 : Wed Aug 22 2012 - 12:00:13 MDT