Search code examples
carmembedded

Cast the return value of a function that returns a casted type


I want to know from compiler perspective what happens when a casted type is returned to a function which also typecast the returned value. I want to know what are the advantages and disadvantages of explicit type casting a return value.

static uint16_t sResult_U16;

static uint16_t GetMyResult(void) 
{
    return (uint16_t)sResult_U16;
}

vs

static uint16_t GetMyResult(void) 
{
    return sResult_U16;
} 

What will compiler translate, if a the return type is not same as the function type? For example.

static int16_t sResult_S16;

static uint16_t GetMyResult(void) 
{
    return sResult_S16;
}

Solution

  • From a compiler's perspective, (uint16_t)sResult_U16; is nonsense since the type of sResult_U16 is already the same as the return type. It will simply ignore the useless cast in the first case.

    In the second case, you use a different type than the return type. The variable is then converted to the same type as the return type, which is in practice done by taking the raw binary representation of the signed variable and convert it to the raw binary unsigned equivalent (the detailed formal rule for this is quoted at the bottom of this answer).


    Formal details can be found in C17 6.8.6.4/3 which says:

    If the expression has a type different from the return type of the function in which it appears, the value is converted as if by assignment to an object having the return type of the function.

    Where "as if by assignment" is the important part - it's the same rule as when using =. So we have to look up the rule for assignment 6.5.15.1:

    In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.

    This conversion happens implicitly, without the need for a cast - the casts in your examples are just clutter.

    In the specific case, an integer conversion from signed to unsigned happens (6.3.1.3):

    Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.