Shouldn't I initialize all my variables? ....for the AVR target, in general, all integer-type variables are set to 0, all pointers to a NULL pointer, and all floating-point variables to 0.0.
I'm trying small program :
#include
int main() { uint8_t test; DDRB=0xFF; PORTB=~test; // LEDs in PORTB is active low
while(1); return 0; }
The result is quite different from FAQ. Sometimes it is zero (all LEDs OFF), sometimes is 0xFF (all LEDs ON). Is anyone having the same experience ? Is it bug in startup C code ?
Also, the reason why this is so is that .bss can be cleared just once, when the program starts. Locals live on the stack, which would have to be cleared every time the function starts, which is considerably more expensive.
All C compilers I have come into contact do it this way.
Scott is correct, most, if not all, C compilers do init static variables and typically zero the .bss segment at startup. This is up to the compiler manufacturer though, the C standard does not require the .bss to be initialized except for where it contains "static" types. The ISO/IEC 1999 C Standard says
6.2.4 Storage durations of objects An object whose identifier is declared with external or internal linkage, or with the storage-class specifier static has static storage duration. Its lifetime is the entire execution of the program and its stored value is initialized only once, prior to program startup.
6.7.8 Initialization If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate. If an object that has static storage duration is not initialized explicitly, then: pointer types are initialized to a null pointer; arithmetic types are initialized to (positive or unsigned) zero; aggregate types, every member is initialized (recursively) according to these rules; unions, the first named member is initialized (recursively) according to these rules.
Stated simply, if you need something to be zero you should specify an initial value or declare it static, i.e., uint8_t test = 0; or static uint8_t test; You can do this either locally within the function or as a global outside of the function.
This is an interesting question that generated instructive answers.
However, for the sake of peace of mind at least, I always initialize variables explicitely. This is less confusing for me and for other unfortunate bug hunters.
You're missing the central clue here: the C standard doesn't even mention the mere existence of something called .bss section. This way deep inside implementation aspects, where the C standard only tells what has to be done, but the C implementors are completely on their own as to how they might do it.
The .bss segment, on those platforms where such a thing exists, will hold those variables of static storage duration that don't have an initializer, plus optionally the initialized ones whose initializer is zero (assuming that all-bits-zero is the correct representation of "zero" for their respective type). Its reason of existence is that it's more efficient for the compiler to synthesize an "initialize all this stuff to all-bits-zero" loop than to have all a master copy of those zeroes occupy space in the executable image of the program (like it has to do with the non-zero initializers). It's, in other words, a crude attempt at data compression to reduce program size. More complicated schemes exists, but they are nowhere near as common as .bss.
No. You don't have to declare an object static for it to be of static storage duration.
--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
You want to compile with the "-Wuninitialized" warning enabled - then the compiler will tell you when you've made a mistake like that. In fact, you should have an extremely good reason not to use "-Wall" or even "-Wall -Wextra" when compiling. Proper use of a lint tool pays off in the long run, but takes some effort at the beginning - the extensive warnings in gcc are a part-way solution that you get for free.
It also does not cost anything. Initalizing statics does not generate code. Theres nothing wrong with the concept of relying on default init states. However, it makes most professional programmers queasy, probally because it shows you haven't really got the complete lifetime of variables in your head.
Of course, the concept of having variables free floating from the code that uses them is why the object folks think procedural coding is inherently dirty, but I digress.
Not true. It costs ROM space for the initializing data. Some compilers will recognize the case when you're initizing with the value zero and put the variable in a "bss" section rather than a "data" section.
True. Unless you have no initialized statics at all, then you can eliminate the startup code that copies the initizing data into the static sections.
--
Grant Edwards grante Yow! Does someone from
at PEORIA have a SHORTER
Yes, but you have to initialize data at some point, it always costs code, or
These compilers are smart, a blessing for clueless programmers who prefer tidy declarations over obfuscated code, that is better left to a cleverer lot;)
Yea, I realized that exception after posting. Its an embedded thing. Operating systems loads don't to the rom thing, they have .data sections embedded in the program file, which just get overwritten in place.
I forgot that the other day and must have appeared fairly stupid, talking about the object code copying the static variables to init them.
Yet another example of why embedded programmers have to *know* their tools. :-)
ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here.
All logos and trade names are the property of their respective owners.