预计表达式错误

时间:2011-11-10 08:10:38

标签: c++ lint

我有以下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,隐式转换更改签名

如何解决上述错误?

6 个答案:

答案 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,但坦率地说,这个 不一定是必要的:00,无论类型如何,等等 可能存在您要强制类型的情况,以确保 算术以某种方式发生,这不是其中之一。至于 错误/警告,我怀疑这也是一个错误的解释 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;