预期表达式错误,发现"WIN32"

Expected an expression error, found 'WIN32'

本文关键字:发现 WIN32 错误 表达式      更新时间:2023-10-16

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

如何修复上述错误?

:

你需要这样做:

#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具有隐式类型强制转换。大多数编译器实际上不会对此发出警告。

有几点需要澄清。例如,

这一行
#if !WIN32

实际上在标准中有很好的定义,可以合理地使用如果你的编译器调用总是包含/DWIN32=1-DWIN32=0。就此而言,标准规定没有定义的符号是在宏扩展时被0代替,所以没有任何问题对于行,除非其他约定声明符号将只在Windows机器上定义,但它定义的值是多少不是指定的;在这种情况下,您需要这样做:

#ifndef WIN32

最后,这取决于你所建立的约定处理编译器依赖项。

另一方面,紧接在后面的行应该避免,因为它定义了一个在C和中定义的符号(ULONG_MAX)c++标准。这里的三行序列应该替换为:

#include <limits.h>

关于第二个问题,我不确定错误是否不是一个MISRA规则的错误解释在c++中,const意味着internal默认链接:在标题中定义这样的符号将导致变量的多个实例化(具有不同的地址)每个翻译单元),但不会造成多个问题定义。替代方案也有其缺点。我的这里首选的是用宏观:

#define CompanyName "mycompany"

但是宏有它们自己的问题。声明符号extern,和然后在一个(且只有一个)源文件中定义它是另一回事可选,但这涉及两个语句,在两个不同的文件中,它可能在哪里(取决于变量所扮演的角色)更可取的。从名字来看,我不认为这两种说法这是一个问题,但在其他情况下,更可取的是保持文本在标题中可见。)就像你写的那样也是一个可行的选择,除非你的公司有严格的规定反对。

关于最后一点,表达式0的类型为int签署。您可以明确地指定类型0UL,但坦率地说,这不应该是必需的:00,无论类型如何,而while在某些情况下,您可能需要强制类型,以确保算术以特定的方式进行,这不是其中之一。至于错误/警告,我怀疑这也是一种误解MISRA规则;可以更改签名的隐式转换有问题,但不是当被转换的是一个非常小的非负常数整数。所以写0UL如果你需要坚持要遵守公司的规定,但要意识到这是在搬运东西愚蠢点:一个基本合理的规则被应用于不相关的情况。

对于第一个问题,我猜你应该用

#ifndef WIN32
不是

#if !WIN32

,因为WIN32宏并不总是存在,你需要检查它是否存在,而不是它的"错误"。

第二个问题,这一行在头文件中吗?一般情况下,您不应该在头文件中定义变量,特别是如果该头文件包含在多个文件中,因为这会创建相同变量的两个副本,并导致链接错误。

还有#if !defined(WIN32),但#ifndef WIN32更容易理解。

这些报告的错误都不是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";

合法,但是个坏主意。如果头文件是来自不同翻译单元的 #included,那么您将有多个CompanyName的定义。(我不太确定c++规则对此有何规定。)参见mystic的回答

第三:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

这里PC-lint过于挑剔了。是的,0(类型为int)到unsigned long的隐式转换确实改变了签名,但在这种情况下,它不会引起任何可能的问题。但是您可以通过使用unsigned long类型的字面值:

来避免此警告。
unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0UL;