MISRA Discussion Forums

Full Version: Rule 14
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Funtions with parameter of type char as for example \"strcpy\" I can not use signed or unsigned char. Eventhoug the compiler specifies that char is signed, whenever you call strcpy with signed char, there is a compilation error, but if we use the parameter of type char, then we violate rule 14. Does this mean that we must generate our own string manipulation functions?
Note that MISRA C1 has been superseded by MISRA C2 the answer refers to MISRA C2 (MISRA-C:2004).

This question is in two parts:

Part 1 asks about the use of plain char in system libraries such as strcpy.

Rule 14 in MISRA C1 does indeed ban the use of plain char requiring it to be signed or unsigned. The clarification in MISRA C2 Rules 6.1, 6.2 and 6.3 is that there are three char types:

Rule 6.1 says plain char shall only be used for characters.
Rule 6.2 says signed and unsigned char shall only be used for numeric types.
Rule 6.3 says the ISO POSIX typedefs should be used.

Therefore you can use:

Code:
unsigned char    uint8_t    /*    for 8 bit integers but   */
    signed char     int8_t    /*    NOT for characters       */
           char     char_t    /*    ONLY for characters      */

This is because char’s are not necessarily the same as 8 bit integers and many standard C libraries use \"char\" which may default to signed or unsigned or even be a multi-byte character.

Part 2 - Use of strcpy

You do not need to write you own version of strcpy. However, re-writing the system header/include files to be MISRA C compliant would be a good idea. We assume your own include files are MISRA C compliant anyway! Note that MISRA C is a coding standard and covers source code (such as the header files) but does not cover the compiled libraries.

As of January 2005 some compiler writers were already making their header files MISRA C compliant. Also any part of the standard library supplied in source for should be MISRA C compliant. Ask your compiler supplier if they are doing so or have plans to do so. Nothing works faster than customer pressure!

With regard to the use of strcpy note the rules on overlapping memory (see Rule 18.2).
Rule 6.1 and 6.2 refer to 'character values' and 'numeric values;
respectively (the response to a question uses the term 'numeric type').
What exactly is a character
or numeric value? This seems to be a general problem with
the new guidelines in that they use terms without defining them.

I guess we might define a character value as a literal delimited
by single quotes and a numeric value as a literal that
is not delimited by single or double quotes. Rules then need
to be defined for the result of arithmetic operations.
For instance, is char_valu_1 + char_valu_2 a character
or numeric value? What about char_valu_1 + 1? Can I apply
the ++ operator to an object having char type?

plieske

derek_farn Wrote:Rules then need
to be defined for the result of arithmetic operations.
For instance, is char_valu_1 + char_valu_2 a character
or numeric value? What about char_valu_1 + 1? Can I apply
the ++ operator to an object having char type?

Common sense would expect that the arithmetic operations are meaningful, this would be no problem for increment and decrement:
> char_value++ is the next character in the character table
> char_value-- is the previous character in the character table

The meaning of binary arithmetic operations are, as Derek already suggested, more interesting. If we treat a character like a pointer into a character table, the meaning would be well-defined:
> char_value + num_value is the character having the distance of num_value in the character table
> char_value_1 - char_value_2 is the distance between the two characters (a numerical value, but is it rather signed or unsigned?)
> char_value_1 + char_value_2 is not valid.
> other arithmetic operators are not allowed

Without having had a look into ISO-C I doubt that the defined behaviour matches with this meaning, and even if it does the source code will be hard to understand, thus being a potential source of bugs.
There are already too many pitfalls with automatic type propagation, so don't add more!

Conclusions:
(1) I would allow increment and decrement on characters (as long as you stay withing the character set and the character set has no gaps).
(2) I would not allow mixing character and numeric values or using binary arithmetic operators on character values UNLESS explicit type conversion functions with a well-defined behavior are used.
By character values, we include all character constants such as

Code:
char_t c1 = 'a';
char_t c2 = '\\n';
char_t c3 = '\\0x41';
char_t c4 = '\\015';

c3 and c4 are set to implementation defined values, which need to be documented under 3.1.

Code:
char_t c5 = 61;

Here 61 is a numeric value, and therefore cannot be assigned to type char_t.

Rule 6.1 states that arithmetic cannot be performed on character types.

The only guaranteed ordered sequence is '0' thru '9'.

Therefore code such as

Code:
c1 = '0' + 3;

is implementation independent, but would still require a deviation against rule 6.1 .