I have following C++ code and running PC lint on code.
Question 1:
#if !WIN32
#define ULONG_MAX 0xffffffff
#endif
Above code is throwing an lint error as follows
Error 26: Expected an expression, found 'WIN32'
Error 30: Expected an integer constant
How to fix above error?
Question 2:
const char CompanyName[] = "mycompany";
Error: Note 960: Violates MISRA Required Rule 8.5, no object/function definitions in header files
How to fix above error?
Question 3:
unsigned long m_ClientThreadId;
m_ClientThreadId = 0;
Note 960: Violates MISRA Required Rule 10.1, Implicit conversion changes signedness
How to fix above error?
Several points need clarification. For example, the line:
#if !WIN32
is actually well defined by the standard, and could be reasonably used
if your compiler invocations always containt /DWIN32=1
or -DWIN32=0
.
For that matter, the standard says that symbols which aren't defined are
replaced by 0
during macro expansion, so there is never any problem
with the line, unless some other convention states that the symbol
will only be defined on Windows machines, but the value it is defined to
isn't specified; in that case, you need something like:
#ifndef WIN32
In the end, it depends on the conventions you've established for handling compiler dependencies.
On the other hand, the line which immediately follows should be avoided,
since it defines a symbol (ULONG_MAX
) which is defined in the C and
C++ standards. The three line sequence here should be replaced by:
#include <limits.h>
With regards to the second question, I'm not sure if the error isn't a
miss-interpretation of the MISRA rule. In C++, const
implies internal
linkage by default: defining the symbol like this in a header will cause
multiple instantiations of the variable (with a different address in
each translation unit), but will not cause problems with multiple
definitions. And the alternatives also have their disadvantages. My
preference here would be to replace the variable definition with a
macro:
#define CompanyName "mycompany"
but macros have their own problems. Declaring the symbol extern
, and
then defining it in one (and only one) source file is another
alternative, but this involves two statements, in two different files,
where (depending on the role the variable plays), one might be
preferable. (Judging by the name, I don't think the two statements
would be an issue, but there are other cases where it is preferable to
keep the text visible in the header.) Leaving it as you've written it
is also a viable alternative, unless your company has strict rules
against it.
With regards to the last point, the expression 0
has type int
, which
is signed. You can clearly specify the type, 0UL
, but frankly, this
shouldn't be necessary: 0
is 0
, regardless of the type, and while
there may be cases where you want to force the type, to ensure that
arithmetic takes place in a certain way, this isn't one of them. As for
the error/warning, I suspect that this is also a mis-interpretation of
the MISRA rules; implicit conversions which change signedness can be
problematic, but not when what is being converted is a very small
non-negative constant integer. So write 0UL
if you need to to adhere
to company rules, but do realize that this is carrying things to the
point of silliness: a case of a basically sound rule being applied in
cases where it isn't relevant.