Search code examples
cembeddedmisra

How to resolve MISRA C:2012 Rule 13.2 and 13.3 for C code?


I have C source code and I am making it MISRA Compliant. I got an following errors related to MISRA 2012 Rule 13.3 and 13.2:

  1. increment/decrement operation combined with other operation with side-effects [MISRA 2012 Rule 13.3, advisory]buf[count++] = U1RXREG;

  2. both sides have side effects [MISRA 2012 Rule 1.3, required], [MISRA 2012 Rule 13.2, required] buf[count] = U1RXREG;

Source code for problem 1:

 void UART_call(void)
 {
    if(count < BUF_SIZE)
    {
        buf[count++] = U1RXREG;
        Flag = 1;
    }
    else
    {
        count = 0;
        Flag = 0;
    }
}

After resolving 13.3 error from problem 1 code I am getting MISRA 1.3 and 13.2 errors. Source code for problem 2:

void UART_call(void)
 {
    if(count < BUF_SIZE)
    {
        buf[count] = U1RXREG;
        count = count + 1U;
        Flag = 1;
    }
    else
    {
        count = 0;
        Flag = 0;
    }
}

Solution

    1. increment/decrement operation combined with other operation with side-effects [MISRA 2012 Rule 13.3, advisory]buf[count++] = U1RXREG;

    This is as you seem to have noted, solved by moving the incrementation out of the assignment expression:

    buf[count] = U1RXREG;
    count++;
    

    The rationale behind this is to prevent writing bugs such as buf[count++] = count;

    1. both sides have side effects [MISRA 2012 Rule 1.3, required], [MISRA 2012 Rule 13.2, required] buf[count] = U1RXREG;

    I'd say this is a false positive. The line buf[count] = U1RXREG; is harmless.

    The reason for the warning is that U1RXREG is obviously a volatile-qualified rx register of the UART hardware, and MISRA-C doesn't like mixing volatile access with other things in the same expression, particularly not with another "side-effect", in this case the ++ of count together with the assignment to buf. It's a common source for false positives from static analysers, though sometimes they do find real bugs related to this, as in the && case you asked about yesterday.

    Assuming 32 bit registers, then the pedantic way to fix it is to use a temporary variable:

    uint32_t rxreg = U1RXREG
    buf[count] = rxreg;
    

    As far as machine code and program behavior are concerned, this is equivalent to the original code.