cembeddedvolatileirq

Return value of static volatile variable in C Function


Two scenarios:

  1. a function that returns the value of a static volatile variable

  2. direct access to a volatile variable

Q1: Will an assignment from a function call behave differently than assignment directly from a volatile variable?

Q2: If so, is there a standard way to access a volatile through a function return?

/*timer.h*/
extern volatile uint8_t directFlag;
uint8_t getReturnFlag(void);



/*timer.c*/
volatile uint8_t directFlag = 0;   
static volatile uint8_t returnFlag = 0;

uint8_t getReturnFlag(void)
{
    return returnFlag;
}

void timerISR(void)
{
    directFlag++;
    returnFlag++;
}



/*main.c*/
#include "timer.h"

void main()
{
    uint8_t a = 0;
    uint8_t b = 0;

    while(1)
    {
        a = directFlag;
        b = getReturnFlag(); /* Can this be optimized out? */

    }
}

Solution

  • In your code almost nothing can be optimized out by a normal compiler. At the moment main.c is compiled, the compiler sees a function call (getReturnFlag()) and it cannot know what possible side effects it contains, and even if it knew it, there is an access to a volatile variable.

    For the very same reason (access to a volatile variable is a side effect) the access to the directFlag variable cannot be optimized out.

    But the values of a and b variables are never used in main.c so both could be optimized out. The code would be equivalent to:

    #include "timer.h"
    
    void main()
    {
        while(1)
        {
            (void) directFlag;
            (void) getReturnFlag(); /* Can this be optimized out? */
    
        }
    }
    

    Unrelated: void main() in only acceptable in a freestanding environment, which I assumed is implied by the embedded tag.

    Now for your questions:

    Will an assignment from a function call behave differently than assignment directly from a volatile variable?

    Access of a volatile variable is an explicit side-effect so a conformant implementation is required to evaluate it. A function call contains potential side effect because common implementations separately compile different translation units and cannot guess whether there will be side effects. But if the definition of the function is in the same translation unit, and the implementation can deduce that there are no side effects (not the case here) it may not evaluate it

    If so, is there a standard way to access a volatile through a function return?

    The function call can only be eliminated if the implementation (compiler) can deduce that no side-effect are produced. If the function access a volatile, a conformant compiler shall not eliminate it