Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 12 May 2012 03:17:01 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Konstantin Belousov <kostikbel@gmail.com>
Cc:        svn-src-head@freebsd.org, svn-src-all@freebsd.org, src-committers@freebsd.org, David Chisnall <theraven@freebsd.org>, Gabor Kovesdan <gabor@freebsd.org>
Subject:   Re: svn commit: r235267 - in head/usr.bin/sort: . nls
Message-ID:  <20120512014148.C1953@besplex.bde.org>
In-Reply-To: <20120511130955.GO2358@deviant.kiev.zoral.com.ua>
References:  <201205111237.q4BCbGX2083596@svn.freebsd.org> <20120511124820.GN2358@deviant.kiev.zoral.com.ua> <6AE99277-D90F-453D-AE40-EE731DFD3BAB@FreeBSD.org> <20120511130955.GO2358@deviant.kiev.zoral.com.ua>

next in thread | previous in thread | raw e-mail | index | archive | help
On Fri, 11 May 2012, Konstantin Belousov wrote:

> On Fri, May 11, 2012 at 08:57:29AM -0400, David Chisnall wrote:
>> On 11 May 2012, at 08:48, Konstantin Belousov wrote:
>>
>>> On Fri, May 11, 2012 at 12:37:16PM +0000, Gabor Kovesdan wrote:
>>>> Author: gabor
>>>> Date: Fri May 11 12:37:16 2012
>>>> New Revision: 235267
>>>> URL: http://svn.freebsd.org/changeset/base/235267
>>>
>>>> +bool byte_sort = false;
>>>> +
>>>> +static wchar_t **wmonths = NULL;
>>>> +static unsigned char **cmonths = NULL;
>>>
>>> Such initializations are useless. You only increase the size of the binary
>>> on the disk as the consequence.

Not even that with some compilers.  For example, not with gcc since
-fzero-initialized-in-bss is the default with gcc.

>> Really? The C specification requires all globals and statics that
>> are not explicitly initialised to be set to their zero value, so this
>> initialisation has no effect on the resulting binary[1]. These are
>> placed in the BSS section, irrespective of whether the initialisation is
>> implicit or explicit and the loader is responsible for allocating space
>> for them - all that is stored in the binary is the size.

THe C specifcation doesn't specify the BSS section, or the any section, or
how variables are implemented.  It barely mentions "memory", and mostly
uses the more generic terms "object" and "storage" instead.

> The initialized variables are placed in .data and not .bss.
> Apparently, some compilers do an optimiziation and put zero-initialized
> objects into .bss, as Colin noted, but this is not guaranteed behaviour.
> If placed in .data, they do consume disk space.
>
> Redundand initialization is not encouraged by style as well.

Yes, this is mainly a style bug.

I noticed some other style bugs in the commit mail.  Mainly:
- logs of extra blank lines
- lots of nested declarations
- excessive nesting of compound statements.  This is especially ugly
   after return.  E.g.:

 	func()
 	{
 		if (foo)
 			return;
 		else {
 			nested declaration;
 			...
 			// most of the function is here
 		}
 	}

>> For local variables, initialisation like this has no effect even
>> at low optimisation levels - dead stores will be removed. It does,
>> however, make it more difficult for the compiler to distinguish between
>> initialised and initialised sensibly in some cases.

It is a larger style bug for local variables.  style(9) even knows about
it (but has been weakened to allow it in some cases).  For compilers,
it breaks any possibility of detecting a variable initialized to a garbage
value (an initial value of 0 may be just as much garbage as a random value).
For humans, it makes lifetime analysis more difficult.

> local variables are irrelevant there.

>> [1] In a standards-compliant compiler. Apparently a few shipping
>> compilers for embedded systems fail to respect this, but everything
>> FreeBSD is compiled with does.

I think the requirement for (as if to) zero-initialization applies
even to freestanding implementations.  The implementation of this for
variables in the BSS is left to crt, so it is mostly out of the
compiler's control.

However, they may be some some boot programs that save space by not
bzeroing the bss.  Not being a C program in this respect apparently
caused the following farcal churn in i386/boot2:
- the opts variable started with a bogus explicit initialization
   to 0.  Long ago (in 2003), but probably after the default of
   -fzero-initialized-in-bss turned this into just a style bug,
   the explicit initializaton was removed.
- zeroing of the bss was moved from i386/boot2/boot1.s ro rbx in 2004.
   It hopefully still worked.
- in 2011, the kname variable was changed from char [1024] to a
   pointer.  The pointer was explicitly initialized to NULL.  This
   was not just a style bug, since the bss was apparently no
   longer zeroed.
- initialization of the opts variable was apparently broken in the
   same way some time before this (whenever the zeroing was optimized
   away).
- in the next commit in 2011, it was claimed that the BSS is not
   zeroed, and the initialization of kname was moved into main()
   to fix this.  bss was spelled BSS, so my greps didn't find this
   immediately.
- in a later commit in 2012, the initialization of opts was moved into
   main(), presumably for the same reason, but neither bss nor BSS was
   mentioned in the commit log, so this took longer to find.
- these changes broke at least kname.  Apparently, it can be initialized
   to non-null before main() in some cases.  This was fixed in the most
   recent commit to boot2.c, in 2012, by moving the initialization of
   kname out of main().  opts was moved similary.  The commit message
   doesn't mention bss or BSS, and says that this is to make clange
   build again.  But boot2 is compiled without -fzero-initialized-in-bss,
   so initializing kname and opts outside of main() has no effect.  They
   are now uninitialized again, assuming that the 2011 commit message is
   correct.  Even the old char array for kname probably needed kname[0]
   to be zero.  We apparently depend on most memory being 0 when booting,
   so that the chance of it being nonzero for these 2 variables is tiny.

kname and opts are the only 2 global variables in i386/boot2 that need
to be initialized to 0 in some way (the others either need to be
initialized to non-0, so they never get put in the bss, or their initial
value doesn't matter.  After reducing kname to a pointer, these variables
have total size 8.  Perhaps the zeroing code would now take more than 8
bytes.  However, in the 2004 version when the zeroing code was in boot1.S,
it size seems to be 6 or 7 bytes (the code for this is smart).  Thus the
savings might be negative, but they are more likely to be a whole 4-8
bytes.  There may be safer ways to save space.

Bruce



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