You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by Eric Lemings <Er...@roguewave.com> on 2008/04/16 18:47:43 UTC
Another style question
I've noticed a lot of #ifdef and #ifndef directives in the code.
Personally, I prefer to always use plain old #if directives since
a compound `#if defined foo || defined bar` is more readable and
consistent with simple #if directives IMHO than
`#ifdef foo || defined bar`.
Just wondering if there is a preference here. Would a simple
`#if defined foo` be permissible?
Brad.
Re: Another style question
Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
>
> Another related question, not so much style-based though.
>
> Why the parentheses around preprocessing symbols in an `#if defined
> (FOO)`
> directive but not in an `#ifdef FOO` directive?
The parentheses are only allowed in the defined operator, not in
the #ifdef/#ifndef directives.
> Example:
>
> $ grep -n "^#if" $SVNROOT/trunk/src/exception.cpp
> ...
> src/exception.cpp:303:#ifdef _RWSTD_NO_EXCEPTION_COPY_CTOR
> src/exception.cpp:307:#if defined (__INTEL_COMPILER)
> ...
>
> For that matter, why use parentheses in a if-def at all?
I can't think of a reason. Feel free not to use them. I might even
join you myself.
Martin
>
> Brad.
>
>> -----Original Message-----
>> From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
>> Sent: Wednesday, April 16, 2008 1:37 PM
>> To: dev@stdcxx.apache.org
>> Subject: Re: Another style question
>>
>> Eric Lemings wrote:
>>>
>> [...]
>>>> Btw., a more flexible way to code these workarounds would have been
>>>> to code it like so:
>>>>
>>>> #if !_RWSTD_NO_MEMBER_TEMPLATES
>>>> // correct code
>>>> #else
>>>> // workaround
>>>> #endif
>>>>
>>>> This way, each config macro could be #defined on the command line
>>>> to 0 or 1 to toggle either branch (e.g., for testing and
>> debugging).
>>>> That's not possible with the #ifndef approach.
>>> From a natural language perspective, I've always found the double
>>> negatives (e.g. `#ifndef _RWSTD_NO_FOO) a bit irritating but that's
>>> just me.
>> I don't like it either but I think it has two important advantages
>> over the alternative (e.g., the GNU HAVE_FOO style). First, in a 100%
>> conforming environment our convention makes it, at least in theory,
>> possible to compile the library without having to configure it,
>> while the other always requires the config tests, or will produce
>> a badly crippled library when none of the config macros is defined.
>> Second, our approach will end up with fewer #defined macros than
>> the other strategy.
>>
>> Martin
>>
RE: Another style question
Posted by Eric Lemings <Er...@roguewave.com>.
Another related question, not so much style-based though.
Why the parentheses around preprocessing symbols in an `#if defined
(FOO)`
directive but not in an `#ifdef FOO` directive? Example:
$ grep -n "^#if" $SVNROOT/trunk/src/exception.cpp
...
src/exception.cpp:303:#ifdef _RWSTD_NO_EXCEPTION_COPY_CTOR
src/exception.cpp:307:#if defined (__INTEL_COMPILER)
...
For that matter, why use parentheses in a if-def at all?
Brad.
> -----Original Message-----
> From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
> Sent: Wednesday, April 16, 2008 1:37 PM
> To: dev@stdcxx.apache.org
> Subject: Re: Another style question
>
> Eric Lemings wrote:
> >
> [...]
> >> Btw., a more flexible way to code these workarounds would have been
> >> to code it like so:
> >>
> >> #if !_RWSTD_NO_MEMBER_TEMPLATES
> >> // correct code
> >> #else
> >> // workaround
> >> #endif
> >>
> >> This way, each config macro could be #defined on the command line
> >> to 0 or 1 to toggle either branch (e.g., for testing and
> debugging).
> >> That's not possible with the #ifndef approach.
> >
> > From a natural language perspective, I've always found the double
> > negatives (e.g. `#ifndef _RWSTD_NO_FOO) a bit irritating but that's
> > just me.
>
> I don't like it either but I think it has two important advantages
> over the alternative (e.g., the GNU HAVE_FOO style). First, in a 100%
> conforming environment our convention makes it, at least in theory,
> possible to compile the library without having to configure it,
> while the other always requires the config tests, or will produce
> a badly crippled library when none of the config macros is defined.
> Second, our approach will end up with fewer #defined macros than
> the other strategy.
>
> Martin
>
Re: Another style question
Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
>
[...]
>> Btw., a more flexible way to code these workarounds would have been
>> to code it like so:
>>
>> #if !_RWSTD_NO_MEMBER_TEMPLATES
>> // correct code
>> #else
>> // workaround
>> #endif
>>
>> This way, each config macro could be #defined on the command line
>> to 0 or 1 to toggle either branch (e.g., for testing and debugging).
>> That's not possible with the #ifndef approach.
>
> From a natural language perspective, I've always found the double
> negatives (e.g. `#ifndef _RWSTD_NO_FOO) a bit irritating but that's
> just me.
I don't like it either but I think it has two important advantages
over the alternative (e.g., the GNU HAVE_FOO style). First, in a 100%
conforming environment our convention makes it, at least in theory,
possible to compile the library without having to configure it,
while the other always requires the config tests, or will produce
a badly crippled library when none of the config macros is defined.
Second, our approach will end up with fewer #defined macros than
the other strategy.
Martin
RE: Another style question
Posted by Eric Lemings <Er...@roguewave.com>.
> -----Original Message-----
> From: Martin Sebor [mailto:msebor@gmail.com] On Behalf Of Martin Sebor
> Sent: Wednesday, April 16, 2008 12:33 PM
> To: dev@stdcxx.apache.org
> Subject: Re: Another style question
>
...
>
> As with every other convention, we're not 100% consistent, only
> about 90% by my count.
Strictly speaking though, the #ifdef and #ifndef directives are
redundant; i.e. `#ifdef foo` and `#if defined foo` are exactly
the same but only the latter form permits compound expressions
(e.g. `#if defined foo || defined bar`).
> Btw., a more flexible way to code these workarounds would have been
> to code it like so:
>
> #if !_RWSTD_NO_MEMBER_TEMPLATES
> // correct code
> #else
> // workaround
> #endif
>
> This way, each config macro could be #defined on the command line
> to 0 or 1 to toggle either branch (e.g., for testing and debugging).
> That's not possible with the #ifndef approach.
>From a natural language perspective, I've always found the double
negatives (e.g. `#ifndef _RWSTD_NO_FOO) a bit irritating but that's
just me.
>
> Incidentally, speaking of #ifdefs, the other convention is to
> add a comment after the #else and #endif directives mentioning
> the name of the macro(s) used in the conditional (or some such
> text) to help see which which branch is active. So according
> to this convention the code above would look like so:
>
> #ifndef _RWSTD_NO_MEMBER_TEMPLATES
> // correct code
> #else // ifdef (_RWSTD_NO_MEMBER_TEMPLATES)
> // workaround
> #endif // _RWSTD_NO_MEMBER_TEMPLATES
Yep. I use this convention myself though I find applying it
unilaterally can be overkill in certain circumstances (e.g.
when there's lots of non-nested #if-#else blocks consisting
of only 5 lines each) but I do it anyway for consistency.
Brad.
Re: Another style question
Posted by Martin Sebor <se...@roguewave.com>.
Eric Lemings wrote:
> I've noticed a lot of #ifdef and #ifndef directives in the code.
Yeah, about 3500 of them.
> Personally, I prefer to always use plain old #if directives since
> a compound `#if defined foo || defined bar` is more readable and
> consistent with simple #if directives IMHO than
> `#ifdef foo || defined bar`.
Only the first (verbose) form is valid. We have close to 900 of
those.
>
> Just wondering if there is a preference here. Would a simple
> `#if defined foo` be permissible?
We've been mostly using the short form for simple conditionals and
the defined operator only when necessary (i.e., in #elif directives
and in #if directives involving boolean expressions).
The rationale is that first, the Rogue Wave C++ Standard Library
style document specified that code that needed workarounds be
guarded by an #ifndef directive, with the correct code first
and the workaround in the #else branch. E.g.,
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
template <class Iterator> void insert (Iterator, Iterator);
#else
// workaround for no member templates
void insert (const_pointer, const_pointer);
#endif
and second, because the macro names tend to be long and the short
form makes the code less verbose.
As with every other convention, we're not 100% consistent, only
about 90% by my count.
Btw., a more flexible way to code these workarounds would have been
to code it like so:
#if !_RWSTD_NO_MEMBER_TEMPLATES
// correct code
#else
// workaround
#endif
This way, each config macro could be #defined on the command line
to 0 or 1 to toggle either branch (e.g., for testing and debugging).
That's not possible with the #ifndef approach.
Incidentally, speaking of #ifdefs, the other convention is to
add a comment after the #else and #endif directives mentioning
the name of the macro(s) used in the conditional (or some such
text) to help see which which branch is active. So according
to this convention the code above would look like so:
#ifndef _RWSTD_NO_MEMBER_TEMPLATES
// correct code
#else // ifdef (_RWSTD_NO_MEMBER_TEMPLATES)
// workaround
#endif // _RWSTD_NO_MEMBER_TEMPLATES
Martin