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.

static volatile char ..or.. static char, which is correct?

All the routines below live in one C file.  Would we need to declare a file global variable xyz as:  static volatile char xyz = 100;   ..or..   static char xyz = 100; ?Basically does the fact that all the routines live in one file allow the compile to "know" xyz is used among multiple functions, and thus needs to be read each time it is needed?

void Task1(void)
{
   while( xyz >= 12 )
   {
      ... some code ...
   }
}

void Task2(void)
{
   while( 1 )
   {
      ... some code that changes the value of xyz ...
   }
}

void MyHwISR(void)
{
   ... some code that sets a value to xyz ...
}

Thanks, Dean

  • Dean Hofstetter said:
    Would we need to declare a file global variable xyz as:  static volatile char xyz = 100;   ..or..   static char xyz = 100; ?

    static char xyz = 100;

    The compiler knows when a call to a function means the value of xyz could change.  Though if you build with --opt_level=3 or higher, the compiler would know whether any given call might modify xyz.

    Thanks and regards,

    -George

  • static char xyz = 100; was our original assumption as well. However, I'm still confused on how the compiler could possibly know it needs to treat xyz as a volatile variable (even though we didn't define it as such).

    In my example, Task1, Task2, and MyHwISR are all independent threads. Task1 has a different priority than Task2, and obviously MyHwISR will trump both the tasks. If I understand you correctly, you are saying the compiler will know to read xyz every time (as if it is volatile)? For example, say Task1 had some code like: while( xyz != 0) { ..this code doesn't change xyz.. }. Task1 is assuming that either Task2 or MyHwISR will change xyz so eventually it will fall out of the while loop. If the optimizer was on, it might determine because xyz is never accessed in the while loop, read it once and use that value forever inside of Task1. Basically never read xyz again, because as far as Task1 is concerned, it isn't changing.

    The only way xyz can be used correctly in my example, is if it is treated like a volatile. Please confirm that static char xyz = 100; is the correct definition.

    Thanks, Dean
  • You do not need to use volatile in this case, because the program's single thread of execution is the only entity responsible for modifying xyz. You only need to use volatile if "something else" might read or write xyz, or in certain obscure cases. See also

    processors.wiki.ti.com/.../Volatile
  • The Volatile link you provided basically states my case: If an object can be modified by an interrupt function (or any other external agent or side effect such as DMA, peripheral device, interrupt, another thread, etc), that variable must be declared volatile.

    I have a task (actually two tasks in this case) that use xyz. I have a hardware interrupt function that changes xyz. By definition I would think volatile is required. The fact I have all three routines in one C file shouldn't matter (at least that is what I'm thinking).

    - Dean
  • Sorry, I missed the fact that one of your routines was named "ISR." Yes, this is a textbook case for where volatile is necessary.

  • I could have been more clear in my original post, sorry about that. Now that we are on the same page (tasks with different priorities and a HW ISR), I have people in my department and perhaps George Mock as well, that think because everything is defined in one file, the compiler will figure it out and the volatile keyword isn't required.

    I disagree and think the volatile keyword is required, and having all the routines in one file has nothing to do with it. George / Archaeologist, can you please comment on this case where all the routines are located in one file.

    Thanks, Dean
  • I have no doubt that George also missed the fact that that function is an ISR. The fact that references are in the same file has nothing to do with the fact that volatile is required here. See C99 section 5.1.2.3 "Program execution", especially footnote 9: "[...] objects referred to by interrupt service routines [...] require explicit specification of volatile storage [...]"
  • Thanks for clearing this up.

    - Dean
  • Archaeologist said:
    I have no doubt that George also missed the fact that that function is an ISR.

    I did.  I confirm that volatile is required in this case.

    Thanks and regards,

    -George