Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #100622

Re: gcc needs a curly bracket matching/counting function

From David Brown <david.brown@hesbynett.no>
Newsgroups comp.lang.c
Subject Re: gcc needs a curly bracket matching/counting function
Date 2016-12-29 12:44 +0100
Organization A noiseless patient Spider
Message-ID <o42srd$b73$1@dont-email.me> (permalink)
References (5 earlier) <o3bvs0$tnf$1@dont-email.me> <lnr352fja1.fsf@kst-u.example.com> <87lgvaiapo.fsf@gmail.com> <lninqefevo.fsf@kst-u.example.com> <kfnlguzy3j6.fsf@x-alumni2.alumni.caltech.edu>

Show all headers | View raw


On 29/12/16 01:36, Tim Rentsch wrote:
> Keith Thompson <kst-u@mib.org> writes:
> 
>> Gareth Owen <gwowen@gmail.com> writes:
>>> Keith Thompson <kst-u@mib.org> writes:
>>>> If the code doesn't use macros, digraphs, or trigraphs to hide braces,
>>>> existing tools can be used to find any missing braces.  If it does, I
>>>> probably don't care about fixing it.
>>>
>>> The only code that I've seen that
>>> a) doesn't (ab)use the features you mention above
>>> b) confuses bracket matchers (emacs, specifically)
>>>
>>> #ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
>>>    if(doohickey != NULL && FROBNICATION_DEPTH < 3) {
>>> #else
>>>    if(doohickey != NULL) {
>>> #endif
>>>       /// Refrobnicate the doohickey
>>>       frobnicate(doohickey);
>>>    }
>>>
>>> That's not a style I would use, or recommend, but I have worked on
>>> codebases with constructs like that in it, and sometimes so many that
>>> refactoring becomes quite an intrusive change.
>>
>> If I felt the need to write code like that, I'd probably put the { on
>> its own line:
>>
>> #ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
>>    if(doohickey != NULL && FROBNICATION_DEPTH < 3)
>> #else
>>    if(doohickey != NULL)
>> #endif
>>    {
>>       /// Refrobnicate the doohickey
>>       frobnicate(doohickey);
>>    }
>>
>> I might even consider writing something like this:
>>
>>    if (doohickey != NULL
>> #ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
>>                          && FROBNICATION_DEPTH < 3
>> #endif
>>                                                   ) {
>>       /// Refrobnicate the doohickey
>>       frobnicate(doohickey);
>>    }
>>
>> though I'd be sympathetic to charges that it's too freaking ugly.
> 
> I hope that you wouldn't choose either of those.  Some
> alternatives (disclaimer: not compiled) -- this:
> 
>     #ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
>     #define FROBNICATION_TEST (FROBNICATION_DEPTH < 3)
>     #else
>     #define FROBNICATION_TEST 1
>     #endif
>     /* ... */
> 
>        if(doohickey != NULL && FROBNICATION_TEST) {
> 

That is a possibility, but is it a good thing to put the definition of
FROBNICATION_TEST far from its usage?  With Keith's version, the real
code is clear at that point in the code.

> 
> Or this:
> 
>     #ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
>     #define AND_POSSIBLE_FROB_TEST(e) ((e) && (FROBNICATION_DEPTH < 3))
>     #else
>     #define AND_POSSIBLE_FROB_TEST(e) (e)
>     #endif
>     /* ... */
> 
>        if(AND_POSSIBLE_FROB_TEST(doohickey != NULL)) {
> 
> 
> It's almost always bad to write #if's (or #ifdef's, etc) in open
> code, eg, inside function bodies.  Better to add a layer of
> abstraction (accomplished here by using a macro, although
> there are other possibilities) to keep the function body
> clean.  Furthermore, if it happens one place, there's a good
> chance it happens or is going to happen somewhere else, in
> which case the preprocessor testing should be factored anyway,
> and the extra layer of abstraction helps with that.
> 

There are many ways to write this sort of thing, each with advantages
and disadvantages.  I agree that it is rarely nice to put #if's in the
middle of a function - but I also think it is good to have related code
close together.

Here are another couple of possibilities.  Without a lot more context
(such as whether these tests are used once or several times) it is hard
to rate the different versions, so I am just airing ideas and not
claiming that one is better than an other.

#ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
static bool doohickeyTest(int* doohickey) {
	return (doohickey != NULL && FROBNICATION_DEPTH < 3);
}
#else
static bool doohickeyTest(int* doohickey) {
	return (doohickey != NULL);
}
#endif

...

if (doohickeyTest(doohickey)) {
	frobnicate(doohickey);
}




#ifdef CAUTIOUS_DOOHICKEY_FROBNICATION
#define SKIP_CAUTIOUS_DOOHICKEY_FROBNICATION false
#else
#define SKIP_CAUTIOUS_DOOHICKEY_FROBNICATION true
#endif

if (doohickey != NULL &&
		(SKIP_CAUTIOUS_DOOHICKEY_FROBNICATION ||
			FROBNICATION_DEPTH < 3)) {
	frobnicate(doohickey);
}



Back to comp.lang.c | Previous | Next — Previous in thread | Find similar | Unroll thread


Thread

Re: gcc needs a curly bracket matching/counting function Tim Rentsch <txr@alumni.caltech.edu> - 2016-12-28 16:36 -0800
  Re: gcc needs a curly bracket matching/counting function David Brown <david.brown@hesbynett.no> - 2016-12-29 12:44 +0100

csiph-web