预期表达式错误,发现"WIN32"
Expected an expression error, found 'WIN32'
我有以下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
,但坦率地说,这不应该是必需的:0
是0
,无论类型如何,而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";
合法,但是个坏主意。如果头文件是来自不同翻译单元的 #include
d,那么您将有多个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;
- Win32编译器选项和内存分配
- C++win32 API创建多个类似视口的窗口
- WM_CTLCOLORSTATIC从未在WIN32应用程序中触发
- 检测win32服务创建和删除的最佳方法
- WIN32:C++,为什么在WM_CLOSE上调用Messagebox函数程序正在冻结
- 将 win32 hbitmap 转换为 winrt softwarebitmap
- 使用 WIN32 API (C/C++) 对特定树视图项进行着色
- Alt+Enter 在 Win32 应用中,管理大小调整和分辨率
- VSCode C++ 编译的exe感染了Win32:TrojanX-gen[Trj]
- 从预处理器获取 Windows 版本(C++ Win32)
- Issues with Win32 ReadProcessMemory API
- Win32 发送输入鼠标移动滞后并冻结
- 如何从 Win32 C++ 应用程序输出到父控制台窗口?
- C++线程:如何在一个线程仍在运行时阻止另一个线程执行 (Win32)
- 将 Win32/WinAPI 应用程序移植到 wxWidgets
- Win32 API 控制台光标在 WriteConsole 后不移动
- C++ Win32 Threads
- C++ win32 如何使密码字段可选并启用复制和粘贴?
- LNK1104:无法打开libpjproject-i386-Win32-vc14-Debug-Static.lib
- 预期表达式错误,发现"WIN32"