MISRA Discussion Forums

Full Version: 16-bit and 32-bit compatibility
You're currently viewing a stripped down version of our content. View the full version with proper formatting.

natapush

1.The expression

u16a = u16b + u16c yields a u16 bit result if int is 16 bits, this means that
u16a = u16b + u16c is compliant on a 16-bit machine.

but
u16a = u16b + u16c yields a signed 32 bit result on a 32-bit machine, so explicit type case has to be used to make the result compliant?
u16a =(u16)(u16b + u16c )

but this is not MISRA comform(rule 10.3 says type has to be narrower as the underlying type)

what is the solution for the expression u16a = u16b + u16c to be MISRA -conform on both machines?(will u16a = (u16)u16b + (u16)u16c also result in integral promotion?)

2. int16_t foo1(uint8_t x)
{
return(20000) compliant on the 16 bit machine
return(20000) not compliant on the 32 bit machine
}

right? (this is from example to rules 10.1-10.2 return(20000))

Gavin McCall

ANSWER: MISRA-C Steering Team

See section 6.10 in MISRA-C:2004.

1. The expression

u16a = u16b + u16c;

Underlying type is used to address this issue.

While the expression u16b + u16c gives a 32-bit result on a 32-bit machine, the underlying type of the expression is U16 regardless of machine architecture.


2.
int16_t foo1(void)
{
return(20000); /* compliant on the 16 bit machine */
return(20000); /* compliant on the 32 bit machine */
return(20000L); /* not compliant on any machine */
return(20000U); /* not compliant on any machine */
}

20000 can be represented in 16 bits, with underlying type of signed 16 bits.

20000L is explicitly long, and at least 32 bits wide, with underlying type of signed long which could be S32, S64 or ...

20000U is explicitly unsigned, with underlying type of unsigned 16 bits. Its use in the return expression involves a change of signedness.

Generally, avoid the use of the long suffix L on integer constants.