avr-gcc : .bss always set variables to zero ?

Here's FAQ that listed in AVR-libc's manual :

  • 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 ?

My development environment is :

  • STK500
  • ATMega8535
  • Linux/ Mandrake 9.2
  • AVR-Libc 1.2.3
  • avr-gcc 3.4.2

Thank you

Reply to
kunil
Loading thread data ...

Only static variables (e.g. .bss sections) are initialized to zero. Automatic variables are going to be undefined.

--
Grant Edwards                   grante             Yow!  I am deeply CONCERNED
                                  at               and I want something GOOD
                               visi.com            for BREAKFAST!
Reply to
Grant Edwards

It seems you ripped this out of context, and missed an important precondition in that process: that behaviour this applies to *static* variables only.

The variable 'test' in your example is automatic, not static. Which means it never ends up in .bss, and thus is not initialized at all.

--
Hans-Bernhard Broeker (broeker@physik.rwth-aachen.de)
Even if all the snow were burnt, ashes would remain.
Reply to
Hans-Bernhard Broeker

Thank you...You're right I miss out the context :p

Reply to
kunil

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.

Reply to
Scott Moore

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.

--
Scott
Validated Software Corp.
Reply to
Not Really Me

outside of

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.

Reply to
Lanarcam

That's cool -- as long as you've got the extra ROM space.

--
Grant Edwards                   grante             Yow!  Is this BOISE??
                                  at               
                               visi.com
Reply to
Grant Edwards

"Not Really Me" wrote in news: snipped-for-privacy@individual.net:

Which is everywhere, basically. automatic variables are not part of the .bss section.

- Fred

Reply to
Fred Viles

initialize

I was fortunate enough not to be that tight;)

This is not simply a cool thing but is required for some classes of applications.

For instance MISRA rule 30 states that: "All automatic variables shall be initialized at declaration"

Example void foo1() { int a; // violation int b=1; // ok int* ptr1; // ok }

Reply to
Lanarcam

No; "static storage duration" does not only mean "with the storage-class specifier static." Note the "or" in section 6.2.4 you cite:

"An object whose identifier is declared with external or internal linkage, OR with the storage-class specifier static has static storage duration."

According to 6.2.2, a non-static global has external linkage:

"If the declaration of an identifier for an object has file scope and no storage-class specifier, its linkage is external."

And thus has static storage duration, and thus is initialized.

--
John W. Temples, III
Reply to
John Temples

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.
Reply to
Hans-Bernhard Broeker

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.

Reply to
David

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.

Reply to
Scott Moore

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
                               visi.com            ATTENTION span than me?
Reply to
Grant Edwards

answers.

initialize

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;)

Reply to
Lanarcam

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. :-)

Reply to
Scott Moore

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.