Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 29 Jan 2005 10:33:22 -0800
From:      Sam Leffler <sam@errno.com>
To:        Robert Watson <rwatson@freebsd.org>
Cc:        Paul Richards <paul@originative.co.uk>
Subject:   Re: c99/c++ localised variable definition
Message-ID:  <41FBD6F2.9050008@errno.com>
In-Reply-To: <Pine.NEB.3.96L.1050129175806.82911K-100000@fledge.watson.org>
References:  <Pine.NEB.3.96L.1050129175806.82911K-100000@fledge.watson.org>

next in thread | previous in thread | raw e-mail | index | archive | help
Robert Watson wrote:
> On Fri, 28 Jan 2005, Garance A Drosihn wrote:
> 
> 
>>At 5:33 PM +0000 1/28/05, Paul Richards wrote:
>>
>>>People used to programming in C++ or Perl (and many others) are
>>>used to defining variables as near to use as possible. This has
>>>never been possible before in C, but now with c99 it is.
>>
>>Well, you could get a similar effect by creating a new scope. 
> 
> 
> And, FWIW, I've been hoping we could eliminate some use of "new scopes" in
> the current code, since they're typically used to hide the fact that
> excessive code is ifdef'd, or that a function should really be two
> functions.  For example, you used to find a moderate amount (and still
> find some) in places like ip_input(), where people would arbitrarily add a
> block of code conditional on a semi-obscure kernel option, and then
> realize they needed variables and make it into a code block.  Where it
> does occur, it's almost always a sign of a problem with the code
> structure.  Here's the sort of thing I mean:
> 
>     int
>     function(void)
>     {
> 
>         /* lots of code */
> 
>     #ifdef BASICALLY_UNUSED_BY_MOST_PEOPLE
>         {
>              struct foo *foo;
>              int x;
> 
>              stuff(foo, x);
>         }
>    #endif

When variables are used only in a limited scope I find it better to 
locate it close to the code rather than some far off spot like the 
outermost block.  Your example above could easily be a case like that. 
Forcing variable declarations to the top of the function means extra 
#ifdef's and makes it easy to forget if you happen to delete or alter 
the code body.

> 
> One of the main situations in which I've found the declaration of
> variables close to their use helpful, as opposed to at the head of the
> function, is for temporary values relating to list or array iteration as
> part of a for loop.  I.e.,
> 
>     for (int i = 0; i < 100; i)) {
> 
>     }
> 
> In this scenario, the re-use of i as part of a broader scope actually
> makes C warnings less useful, since you lose the benefit of stuff like
> "used but not initialized" warnings as the variables are reused.  Maybe
> what we should be doing is identifying a couple of places where we are
> willing to take this approach, and it offers a clear benefit, and
> specifically pointing at those.  I have to say that the type of coding
> style that annoys me somewhat to read in blended C/C++ code is this sort
> of thing: 
> 
>     struct big foo;
> 
>     // ... large block of code
> 
>     struct another_big bar;
> 
>     // ... large block of code
> 
> In environments with constrained stacks, especially in the kernel or
> threaded applications, having all the serious declarations up front makes
> it much easier to decide if things are getting out of hand.  That's one
> reason why things like ancillary counter variables seem reasonable, but
> more extensive use can be problematic. 

One thing I especially like about c++'s ability to declare variables 
mid-block in that it lets you insure variables are initialized by 
combining declaration and initialization.  That is instead of

	int needed_somewhere_way_far_away;
	...lots of code...
	needed_somewhere_way_far_away = something_not_available_at_top_of_function;

you can combine the decl and the initialization.  This is a requirement 
when you want to use const.

	Sam


Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?41FBD6F2.9050008>