1 .. title:: clang-tidy - bugprone-signed-char-misuse
3 bugprone-signed-char-misuse
4 ===========================
6 `cert-str34-c` redirects here as an alias for this check. For the CERT alias,
7 the `DiagnoseSignedUnsignedCharComparisons` option is set to `false`.
9 Finds those ``signed char`` -> integer conversions which might indicate a
10 programming error. The basic problem with the ``signed char``, that it might
11 store the non-ASCII characters as negative values. This behavior can cause a
12 misunderstanding of the written code both when an explicit and when an
13 implicit conversion happens.
15 When the code contains an explicit ``signed char`` -> integer conversion, the
16 human programmer probably expects that the converted value matches with the
17 character code (a value from [0..255]), however, the actual value is in
18 [-128..127] interval. To avoid this kind of misinterpretation, the desired way
19 of converting from a ``signed char`` to an integer value is converting to
20 ``unsigned char`` first, which stores all the characters in the positive [0..255]
21 interval which matches the known character codes.
23 In case of implicit conversion, the programmer might not actually be aware
24 that a conversion happened and char value is used as an integer. There are
25 some use cases when this unawareness might lead to a functionally imperfect code.
26 For example, checking the equality of a ``signed char`` and an ``unsigned char``
27 variable is something we should avoid in C++ code. During this comparison,
28 the two variables are converted to integers which have different value ranges.
29 For ``signed char``, the non-ASCII characters are stored as a value in [-128..-1]
30 interval, while the same characters are stored in the [128..255] interval for
33 It depends on the actual platform whether plain ``char`` is handled as ``signed char``
34 by default and so it is caught by this check or not. To change the default behavior
35 you can use ``-funsigned-char`` and ``-fsigned-char`` compilation options.
37 Currently, this check warns in the following cases:
38 - ``signed char`` is assigned to an integer variable
39 - ``signed char`` and ``unsigned char`` are compared with equality/inequality operator
40 - ``signed char`` is converted to an integer in the array subscript
43 `STR34-C. Cast characters to unsigned char before converting to larger integer sizes
44 <https://wiki.sei.cmu.edu/confluence/display/c/STR34-C.+Cast+characters+to+unsigned+char+before+converting+to+larger+integer+sizes>`_
46 A good example from the CERT description when a ``char`` variable is used to
47 read from a file that might contain non-ASCII characters. The problem comes
48 up when the code uses the ``-1`` integer value as EOF, while the 255 character
49 code is also stored as ``-1`` in two's complement form of char type.
50 See a simple example of this below. This code stops not only when it reaches
51 the end of the file, but also when it gets a character with the 255 code.
61 if (readChar(CChar)) {
67 A proper way to fix the code above is converting the ``char`` variable to
68 an ``unsigned char`` value first.
78 if (readChar(CChar)) {
79 IChar = static_cast<unsigned char>(CChar);
84 Another use case is checking the equality of two ``char`` variables with
85 different signedness. Inside the non-ASCII value range this comparison between
86 a ``signed char`` and an ``unsigned char`` always returns ``false``.
90 bool compare(signed char SChar, unsigned char USChar) {
96 The easiest way to fix this kind of comparison is casting one of the arguments,
97 so both arguments will have the same type.
101 bool compare(signed char SChar, unsigned char USChar) {
102 if (static_cast<unsigned char>(SChar) == USChar)
107 .. option:: CharTypdefsToIgnore
109 A semicolon-separated list of typedef names. In this list, we can list
110 typedefs for ``char`` or ``signed char``, which will be ignored by the
111 check. This is useful when a typedef introduces an integer alias like
112 ``sal_Int8`` or ``int8_t``. In this case, human misinterpretation is not
115 .. option:: DiagnoseSignedUnsignedCharComparisons
117 When `true`, the check will warn on ``signed char``/``unsigned char`` comparisons,
118 otherwise these comparisons are ignored. By default, this option is set to `true`.