Search code examples
clocal-variables

(Conditional?) creation of local variables in function


I came across this [question]: How can I store values into a multi-parameter struct and pass typedef struct to a function?. I suggested declaring a variable of dtErrorMessage once before the if and use it for both conditions instead of declaring two different variables as shown here:

// Initial version
if(GetTemperature() <= -20)
{
    dtErrorMessage low;
    low.errorCode=ERROR_CODE_UNDER_TEMP;
    low.temperature=GetTemperature();
    SendErrorReport(&low);
}

if(GetTemperature() >= 160)
{
    dtErrorMessage high;
    high.errorCode=ERROR_CODE_OVER_TEMP;
    high.temperature=GetTemperature();
    SendErrorReport(&high);
}


// My version
dtErrorMessage err;
int8_t temp = GetTemperature();       // Do not consider change during evaluation

if(temp <= -20)
{
    err.errorCode   = ERROR_CODE_UNDER_TEMP;
    err.temperature = temp;
    SendErrorReport(&err);
}
else if(temp >= 160)
{
    err.errorCode   = ERROR_CODE_OVER_TEMP;
    err.temperature = temp ;
    SendErrorReport(&err);
}
else
{
  // Do not send error report 
}

My question is: (Under the embedded aspect,) am I right, that this way there will be two local variables created in RAM regardless of the condition? Consequently, it would reduce the reqired RAM using one unconditional variable declaration before the if and then using it for both conditions, right?

I couldn't find the correct terms to search for getting this answered myself.


Solution

  • The lifetime of a variable with automatic storage duration is until the end of the block. Storage will be guaranteed and it will retain constant address (i.e. the address given by e.g. &) until the end of the block, and after that all pointers to that object will become indeterminate.

    The C standard does not say that low and high must occupy the same portion of memory! The storage must be guaranteed until the end of the block containing the declaration, but it can be around longer too. On the other hand the as-if rule says that the program needs to only behave as if it was a program compiled for the abstract machine according to the rules of the C standard, so a high-quality implementation would probably

    • not reserve memory for both low and high simultaneously at different addresses, and
    • not reserve memory for err in case the else branch is taken.

    In effect making the execution behaviour of these 2 virtually identical.

    The difference is mostly stylistic: in your version there is less to type, and the original version accommodates for bad compilers.