我有以下C ++代码并在代码上运行PC lint。
问题1:
#if !WIN32
#define ULONG_MAX 0xffffffff
#endif
上面的代码抛出一个lint错误如下
错误26:预期表达式,找到'WIN32'
错误30:预期整数常量
如何解决上述错误?
问题2:
const char CompanyName[] = "mycompany";
错误:注意960:违反MISRA要求规则8.5,头文件中没有对象/函数定义
如何解决上述错误?
问题3:
unsigned long m_ClientThreadId;
m_ClientThreadId = 0;
注960:违反MISRA要求规则10.1,隐式转换更改签名
如何解决上述错误?
答案 0 :(得分:4)
<强>首先强>
你需要这样做:
#ifndef WIN32
#define ULONG_MAX 0xffffffff
#endif
<强>第二强>
您无法在头文件中定义它,否则相同的符号将出现在多个编译单元中。
您需要做的只是在标题中声明:
extern const char CompanyName[];
然后在其中一个模块中定义一次:
const char CompanyName[] = "mycompany";
<强>第三强>
unsigned long m_ClientThreadId;
m_ClientThreadId = 0;
这很不寻常,但似乎0
是一个有符号常数。并将其分配给unsigned long
具有隐式类型转换。大多数编译器实际上并没有对此发出警告。
答案 1 :(得分:2)
有几点需要澄清。例如,行:
#if !WIN32
实际上是由标准定义的,并且可以合理地使用
如果您的编译器调用始终包含/DWIN32=1
或-DWIN32=0
。
就此而言,标准规定未定义的符号是
在宏扩展期间由0
替换,因此从来没有任何问题
使用该行,除非某些其他约定表明该符号
将仅在Windows计算机上定义,但定义为它的值
未指定;在这种情况下,你需要像:
#ifndef WIN32
最后,它取决于您为之建立的惯例 处理编译器依赖。
另一方面,应该避免紧接着的线,
因为它定义了一个符号(ULONG_MAX
),它在C和C中定义
C ++标准。这里的三行序列应替换为:
#include <limits.h>
关于第二个问题,我不确定错误是不是
错误解释MISRA规则。在C ++中,const
意味着内部
默认情况下链接:在标题中定义这样的符号将导致
变量的多个实例化(具有不同的地址)
每个翻译单元),但不会导致多重问题
定义。替代方案也有其缺点。我的
这里的首选项是用a替换变量定义
宏:
#define CompanyName "mycompany"
但宏有自己的问题。声明符号extern
,和
然后在一个(也是唯一一个)源文件中定义它是另一个
替代方案,但这涉及两个语句,在两个不同的文件中,
其中(取决于变量所扮演的角色),可能是
优选的。 (从名称来看,我不认为这两个陈述
将是一个问题,但在其他情况下,它是优选的
保持文本在标题中可见。)在写完文章时保留文本
除非贵公司有严格的规定,否则也是一个可行的选择
反对它。
关于最后一点,表达式0
具有类型int
,其中
签了。您可以清楚地指定类型0UL
,但坦率地说,这个
不一定是必要的:0
是0
,无论类型如何,等等
可能存在您要强制类型的情况,以确保
算术以某种方式发生,这不是其中之一。至于
错误/警告,我怀疑这也是一个错误的解释
MISRA规则;隐式转换可以改变签名
有问题,但不是什么时候转换的是一个非常小的
非负常数整数。如果你需要坚持,请写0UL
对公司规则,但确实意识到这是携带的东西
愚蠢的一点:应用基本合理的规则的情况
不相关的情况。
答案 2 :(得分:1)
对于第一个问题,我猜你应该使用
#ifndef WIN32
而不是
#if !WIN32
因为WIN32宏并不总是存在,你需要检查它的存在而不是它的“虚假”。
答案 3 :(得分:0)
对于问题二,是头文件中的那一行吗?您通常不应在标头中定义变量,特别是如果该标头包含在多个文件中,因为这将创建同一变量的两个副本,并将导致链接错误。
答案 4 :(得分:0)
还有#if !defined(WIN32)
,但#ifndef WIN32
更容易理解。
答案 5 :(得分:0)
这些报告的错误都不是C ++错误;他们是风格问题。
<强>首先强>
#if !WIN32
#define ULONG_MAX 0xffffffff
#endif
这是合法的。在#if
指令中,任何未定义的令牌都将替换为0
。但是,正如其他人已经建议的那样,写#ifndef WIN32
可能是更好的风格。
但实际上,整个事情可能是一个坏主意。 ULONG_MAX
是在C标准头<limits.h>
中定义的宏,以及C ++标准头<climits>
。将以上3行替换为:
#include <climits>
<强>第二强>
const char CompanyName[] = "mycompany";
合法,但不是个好主意。如果头文件来自不同的翻译单元#include
,则您将拥有CompanyName
的多个定义。 (我不太清楚C ++规则对此有何看法。)见Mysticial的答案。
<强>第三强>
unsigned long m_ClientThreadId;
m_ClientThreadId = 0;
这里PC-lint过于挑剔。是的,0
(类型为int
)到unsigned long
的隐式转换确实会改变签名,但在这种情况下,它不会导致任何可能的问题。但是你可以通过使用unsigned long类型的文字来避免警告:
unsigned long m_ClientThreadId;
m_ClientThreadId = 0UL;