I'm organizing Klocwork rules and clearing out any issues found by static analysis. There are multiple rules applied and currently I'm having an issue with specifying character literals. Let's consider this example:
for (const char* p = str; *p != '\0'; ++p)
As you can see, this is loop iterating over C-String. It's used to utilize unordered_map of constexpr string literals. Performance measurements proved that storing them as std::string increases memory usage and affects performance because of overhead. As this map content is constant, I'm using custom hash functor for C-Strings (again, to avoid conversions and copying string to std::string just to generate hash). Simple answer would be using std::string_view but it's not available in this environment. So the problem comes from condition itself. The condition should check if character is terminating null.
Obviously at first I used !p
as it's guaranteed by standard that terminating null resolves to false (no matter what is the real type of char). It results in AUTOSAR C++14 (18-03) error MISRA.STMT.COND.NOT_BOOLEAN
which translates to "Condition of if or loop statement has type 'char' instead of 'boolean'".
Ok then, I changed that to explicit comparison p != 0
and it turned out to be MISRA.CHAR.NOT_CHARACTER
violation which is "'char' is used for non-character value".
Again, that's valid point as I'm comparing char to int but char is neither int nor unsigned int. Therefore I changed it to *p != '\0'
which should directly translate to null character. This in turn gives MISRA.LITERAL.UNSIGNED.SUFFIX
violation which is "Unsigned integer literal ''\0'' without the 'U' suffix". Now I'm surprised. Even if char is considered to be unsigned in one compiler, it is not guaranteed to be either signed or unsigned, so I can't hardcode it to any sign. Not even mentioning that there seems to be no way of specifying suffix for character literals. In my opinion it's already false positive as '\0'
IS char type and should not require any further conversion or cast. This shows even more visible issue with syntax like uri.find_last_of('/')
where I'm looking for specific character, not particular value. This case generates the same error complaining that I did not specify suffix. (uri is std::string)
My guess is that this is false positive from bugged filter implementation. Also it seems like static analysis might be misconfigured as character literals are considered to be integer only in C, not in C++.
As side note I'll add that in first example using *p != char(0)
resolved this issue but that's far from preferred solution and can only be used with known integer value of character which is far less flexible and error prone than using literals thus I'm not going to use this workaround.
What are your thoughts about this issue? Maybe someone else already got such Klocwork error and found solution other than disabling rule or suppressing it for every literal character instance. I already have my list of common false positives that quite often come from C++11 and newer standards checked by rules based on MISRA 2008 C++.