On 18/02/13 18:08, Robert Dewar wrote:

Forgive me, but I don't see where anything is guaranteed to be zero'd
before use. I'm likely wrong somewhere since you disagree.

http://en.wikipedia.org/wiki/.bss

This is about what happens to work, and specifically notes that it is
not part of the C standard. There is a big difference between programs
that obey the standard, and those that don't but happen to work on some
systems. The latter programs have latent bugs that can definitely
cause trouble.

A properly written C program should avoid uninitialized variables, just
as a properly written Ada program should avoid them.

In GNAT, we have found the Initialize_Scalars pragma to be very useful
in finding uninitialized variables. It causes all scalars to be
initialized using a specified bit pattern that can be specified at
link time, and modified at run-time.

If you run a program with different patterns, it should give the same
result, if it does not, you have an uninitialized variable or other
non-standard aspect in your program which should be tracked down and
fixed.

Note that the BSS-is-always-zero guarantee often does not apply when
embedded programs are restarted, so it is by no means a universal
guarantee.



I believe the standards require that all statically allocated data without an explicit initialisation are initialised to a /value/ of zero. The standards do not require values of zero to actually be zero bits - it is legal for null pointers, 0 integers, and 0.0 floats and doubles to have different representations. It is also perfectly legal for the compiler to put uninitialised data somewhere other than ".bss". But the standards do guarantee that a definition "int x;" has the same effect as "int x = 0;" - and similarly for all other statically allocated data.


In embedded systems, any C startup code (the code that is run before main() is called) that does not clear the bss is dangerously broken. (I know of no real-world embedded processors where 0 is /not/ represented as zero bits.) There are a few toolchains that /are/ broken in this way - Texas Instruments's "Code Composer" is a prime example. The manual mentions this briefly at one point - to paraphrase, "the C startup code does not clear the bss at startup. We know this is against every C standard - but we never claimed to follow any particular C standard anyway".

So if you know that you will be working with broken compilers that don't follow such fundamental parts of the C standards, then you should not rely on the automatic zero initialisation. But if you are using real working toolchains, then you (as an embedded programmer) /should/ rely on it - because it leads to smaller and faster code than explicitly initialising them to zero. (Of course, sometimes you want to be explicit in initialising to zero for clarity of the program - this trumps efficiency every time.)


Reply via email to