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.

Variable scope

Other Parts Discussed in Thread: MSP430FR5739

I little confused about variable defenition in the following code:

#include <msp430.h>

int b = 3;

int main(void) {
  WDTCTL = WDTPW | WDTHOLD; // Stop watchdog timer

  b=2;

  for(;;){;}

  return 0;
}

When I debug the program and watch the variable 'b', why does it not initialize to value of 3?  It does change to value of 2 as I step through the program, but why would it not initialize to value of 3?

My uC is MSP430FR5739, IDE is CCS 5.3

  • If you compiler the above code with active code optimization, this may have some side-effects on how the debugger sees variables.

    It's psosible that B is initialized to 3, but when the debugger stops at main, it gets the information that because of optimization considerations, the compiler has assigned B to a register and immediately initialized it with 2 already (because it doesn't make a difference when b is changed to 2 in this code). Or the compiler might have set b to 2 right at the beginnign of main, before any registers are used for something else, for the very same reason.

    If you encounter anything that looks strange in the debugger, disable optimization and check again. Main putrpose of code optimization is to keep the outcome identical while shrinkign the code or the execution times (or both), not to stick on the order given in the source code.

    If you need to have things treated exactly in order, declare them as volatile. (all MSP hardware registers are declared volatile) This tells the compiler that access to a (global!) variable may have side-effects not discoverable by analyzing the source code flow. Then optimization on these global variables is deactivated.

  • I turned optimization OFF, but this issue persists.  If I run this on IAR Workbench, it runs as expected.  Why?  This is driving me crazy !!!!

  • Uninstalled every TI piece of software from my PC, reinstalled CCS5.3 it, and now I am using compiler version 4.1.2 and it seems to work. 

  • Silver Diamond said:
    If I run this on <insert toolset name here>,  it runs as expected.  Why?  

    Because your expectation is incorrect!

    A High-Level Language (HLL) Compiler is not required to slavishly transliterate each source line into an exactly-corresponding, 1:1 matching, set of machine instructions.

    A HLL Compiler is perfectly entitled to remove useless code - whether or not you enable so-called "optimisations".

    In fact, in this case, the Compiler would be perfectly entitled to remove the variable completely, as it is never used! It has no observable effect on the program's behaviour.

    See: http://e2e.ti.com/support/microcontrollers/msp43016-bit_ultra-low_power_mcus/f/166/p/240059/841822.aspx#841822

    Silver Diamond said:
    now I am using  <insert another toolset name here>   and it seems to work. 

    It was "working" before - within the definition of the 'C' programming language.

    Modern compilers are very clever. This is very good for producing "tight" code for small, memory-constrained microcontrollers - but means that trivial examples like this cannot be relied upon.

    Compilers also get better as newer versions are released - or, at least, one would very much hope that they should get better!
    Therefore it is not uncommon for flawed code that "worked" (sic) on an older version of compiler to stop working with a newer version having more vigorous optimisations.

    Similarly, it is common for flawed code that "worked" (sic) with low or no so-called "optimisation" to fail at higher levels of optimisation.

    This is a very common beginner's misconception - just search the forums for "optimisation"...!

  • Andy,

    Thank you, these are all great points and it does clear up some things in my mind.  But in this case I was hitting my head against the wall because something caused the CCS installation not to work properly.  I am almost wondering if installing MinGW (I use it to debug functions and classes) caused this issue.  What helped me is knowing that people are not finding an issue with what I am doing, I understood that there is something wrong with the system and it pointed me to re install   So, anyway, thank you for your input.

  • Indeed, a MinGW (or anything that is based on make)  installation may cause the system to use the wrong make or even the wrong compiler. Usually you'll get lots of errors then.
    At least it may disable some GCC specific tweaks in teh build chain by using the wrong version of the tools.

  • Silver Diamond said:
    But in this case I was hitting my head against the wall because something caused the CCS installation not to work properly

    But what you posted didn't actually show anything "not working" or "wrong" - as explained, it is perfectly acceptable behaviour for the compiler "optimisation" to give the effect that you described.

    Or are you referring to something else?

     

  • Silver Diamond said:
    why does it not initialize to value of 3?

    Well.. Actually you don't initialize it right :) To let global variable be valid at any time - when you with debugger or your IRQ code look at it, you shall use "volatile" keyword:

    volatile int b = 3;

  • Ilmars said:
    you shall use "volatile"

    Well, in this case, it is an initialized global variable. So it should be 3 right after executing the startup code. Independent of what main or an ISR will later do.
    So at start of main, it should be 3. Whther it turns 2 right with the first instruciton of main or later or not at all is a different thing.

    The produced assembly code of main would be interesting.

  • Jens-Michael Gross said:
    Whther it turns 2 right with the first instruciton of main or later or not at all is a different thing.

    Strongly disagree. Compiler cannot know about IRQ routine in other modules reading particular variable (at any time), so it must set it to 2 disregarding fact that main() code does not need result of particular assignment.

  • Ilmars said:
    Strongly disagree. Compiler cannot know about IRQ routine in other modules reading particular variable (at any time),

    This is a common mistake.

    The compiler does not know of things like interrupts. The C language works on a straight code flow. Everything magical, like ISRs or hardware registers that read vlaues or change content, are an unknown thing to the C language.
    If such a thing happens, then you'll need to tell the compiler that a variable is 'special' in that accessing it may have side-effects outside the language scope. THis is done with the volatile keyword. If you add it to a variable (all hardware registers are volatile variables), the compiler generates an access to it exactly as often and when it happens in the source code. Of course, this makes handling these variables inefficient and blocks any optimization attempts. So it has to be done exactly when it is necessary and not precautiously on every variable.

    In this case, since b was not declared volatile, it is just a memory cell for the compiler, that is accessed throughout the sequential course of the program. And subject to optimization up to being ignored totally.

  • Andy Neil said:
    Because your expectation is incorrect!

    Another example here:

    http://e2e.ti.com/support/microcontrollers/msp430/f/166/t/244977.aspx

  • Thank you for all of your inputs, but pressing button "Restore Defaults" worked like a charm.  I must have changed a setting that caused this problem.

    \

  • Silver Diamond said:
     I must have changed a setting that caused this problem (sic)

    But, again, you have not show any actual problem in the behaviour of the tools!

    The so-called "problem" is, in fact, perfectly valid and correct behaviour - until you understand this, you will keep falling into the same trap!

**Attention** This is a public forum