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>