This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430 GCC 4.8 - Global variables in .noinit rather than .bss

Other Parts Discussed in Thread: ENERGIA

Hi folks-

Another hobbyist playing with the new GCC 4.8 compiler noticed an oddity that is inconsistent at least with the older MSPGCC.  The linker section *(COMMON), which seems to store global variables, is in the ".noinit" section in the linker scripts provided with the GCC 4.8 install.

This means uninitialized globals such as:

volatile unsigned short sleep_counter;

would end up in .noinit, where its value is not necessarily initialized (to 0) on powerup like it would if it were in the ".bss" segment.  On the older MSPGCC, *(COMMON) was stored in .bss and initialized to 0 on reset every time.

It seems this compiler will put a global variable into .bss if you give it an initializer of 0:

volatile unsigned short sleep_counter = 0;

and into the .data section if you give it a non-zero initializer:

volatile unsigned short sleep_counter = 5;

which is as expected.  Is this ".noinit" for globals w/o explicit value declaration a general policy that TI is sticking with for the GCC environment?

  • Hi Eric,

    I will look into this.

    Regards,

    Katie

  • Thanks Katie.  Fwiw, I think the "expected" behavior of *(COMMON) living in .bss is also the case on ARM toolchains, and e.g. for Energia 12, the linker script for the Tiva series chips puts *(COMMON) in .bss.  Without this there's just an unexpected "quirk" users should know about... their global arrays & variables might not be auto-initialized to 0x00 as they may expect.

  • Not initializing uninitialized variables to 0 was the way CCS did do it in COFF mode.
    Also, the (original) C standard does not require this, and it reduces problems with the watchdog at startup.
    If you need a variable initialized, then say so in your code.

    Also, uninitialized variables silently link between different C modules, which may cause hard to track problems if the two modules don’t know of each other. If two modules contain a "int x;", both are joined into one even though they are probably used for two different purposes. If both modules do a "int x = 0;" then you'll get a linker error and notice that something is going wrong.

    I guess, initializing uninitialized variables to 0 derives from the bad habit of PC programs to load the variable initializations 1:1  from file to memory on startup. So the uninitialized ones did need a file content. And people got use to having them initialized to 0, as this was what the compilers picked to put into the file. Could have been any value. On MSP, where storage is limited, it makes no sense to store large areas of zero bytes just for initialization. So non-zero initialized data is put in its own segment and copied from flash to ram, while zero-initialized is simply filled. And non-initialized, well, may remain non-initialized or zeroed, unless you intentionally need it non-initialized (for persistence across a reset).

**Attention** This is a public forum