today I've catched quite unfamiliar situation with my code. I've changed type of variable passed as parameter to function - from unsigned char to unsigned short and...there was no warning! On the debug I saw that variable's value is truncated and rest of the functio happily play with half of value without any problem....what the heck?!
Below short code snippet:
void func1(unsigned char param)
{
if(param == 0x02) //even if passed parameter is 0x0102, truncated data fits and enter branch
{
__asm("nop"); //just anything to avoid optimization
}
}
void func2(void)
{
unsigned short param_test = 0x0102;
unsigned char test2;
test2 = param_test; //completely fine for compiler, "test2" stores 0x02 value
(void)test2; //to avoid compiler warning of not used variable
func1(param_test);
}
IAR compiler doesn't see any problem to not inform programmer that something may not work as intended...
Windows C compiler is VS at least return warning C4244: "conversion from unsigned short to unsigned char, possible loss of data". Is there any flag for IAR as well? I couldn't find it yet...
From the Annex I of the ISO/IEC 9899:1999 C Language Specification:
An implementation may generate warnings in many situations, none of which are specified as part of this International Standard. The following are a few of the more common situations. [...]
- An implicit narrowing conversion is encountered, such as the assignment of a
long int
or adouble
to anint
, or a pointer tovoid
to a pointer to any type other than a character type (6.3).[...]
Meaning that, according to the standard, the char
type is not "generally" entitled for warning.
One potential solution, based on this particular question, is to pass the parameter as a pointer in the func1()
function:
#include <stdbool.h>
bool func1(unsigned char *param);
bool func1(unsigned char *param)
{
return (*param == 0x02);
}
Under such situation, the compiler will generate a compile time error when trying to pass a pointer to a short
:
func1(¶m_test);
will fail with Error[Pe167]: argument of type "unsigned short *" is incompatible with parameter of "unsigned char *"
.
In general, such practice can help to catch bugs at compile time with a potentially good side effect of saving some cycles.