简体   繁体   English

预期表达错误

[英]Expected an expression error

I have following C++ code and running PC lint on code. 我有以下C ++代码并在代码上运行PC Lint。

Question 1: 问题1:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

Above code is throwing an lint error as follows 上面的代码抛出一个皮棉错误,如下所示

Error 26: Expected an expression, found 'WIN32' 错误26:预期为表达式,找到“ WIN32”
Error 30: Expected an integer constant 错误30:预期为整数常数

How to fix above error? 如何解决以上错误?

Question 2: 问题2:

const char CompanyName[] = "mycompany"; 

Error: Note 960: Violates MISRA Required Rule 8.5, no object/function definitions in header files 错误:注释960:违反了MISRA要求的规则8.5,头文件中没有对象/函数定义

How to fix above error? 如何解决以上错误?

Question 3: 问题3:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Note 960: Violates MISRA Required Rule 10.1, Implicit conversion changes signedness 注释960:违反了MISRA要求的规则10.1,隐式转换更改了签名

How to fix above error? 如何解决以上错误?

First: 第一:

You need to do this instead: 您需要这样做:

#ifndef WIN32
#define ULONG_MAX 0xffffffff
#endif

Second: 第二:

You can't define that in a header file, otherwise the same symbol will appear in multiple compilation units. 您不能在头文件中定义它,否则相同的符号将出现在多个编译单元中。

What you need to do instead, is just declare in the header: 您需要做的只是在标头中声明:

extern const char CompanyName[];

And then define it once in one of the modules: 然后在以下模块之一中对其进行定义:

const char CompanyName[] = "mycompany"; 

Third: 第三:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

This is unusual, but it seems that 0 is a signed constant. 这是不寻常的,但似乎0是有符号常量。 And assigning it to unsigned long has a implicit type cast. 并将其分配给unsigned long具有隐式类型转换。 Most compilers do not actually warn against this. 大多数编译器实际上并未对此提出警告。

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 . 由标准实际上很好地定义,并且如果编译器调用始终包含/DWIN32=1-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; 为此,该标准表示,宏扩展期间未定义的符号将替换为0 ,因此该行永远不会有任何问题, 除非某些其他约定指出该符号仅在Windows计算机上定义,但是未定义定义的值; 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. 另一方面,应避免紧随其后的那一行,因为它定义了在C和C ++标准中定义的符号( ULONG_MAX )。 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. 关于第二个问题,我不确定该错误是否是对MISRA规则的误解。 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. 在C ++中,默认情况下const表示内部链接:在标头中定义这样的符号将导致变量的多个实例化(每个转换单元中的地址不同),但不会导致多个定义出现问题。 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. 声明符号extern ,然后在一个(只有一个)源文件中对其进行定义是另一种选择,但这涉及两个语句,在两个不同的文件中,其中(取决于变量所扮演的角色),一个语句可能更可取。 (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. 关于最后一点,表达式0具有类型int ,该类型为有符号。 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. 您可以清楚地指定类型0UL ,但坦率地说,不必指定: 00 ,而不管类型如何,并且在某些情况下您想强制使用该类型,以确保算术在a中进行。以某种方式,这不是其中之一。 As for the error/warning, I suspect that this is also a mis-interpretation of the MISRA rules; 至于错误/警告,我怀疑这也是对MISRA规则的误解; 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. 因此,如果您需要遵守公司规则,请写0UL ,但一定要意识到这将事情带到了愚蠢的地步:在不相关的情况下应用了基本合理的规则。

For the first question, I'd guess the you should use 对于第一个问题,我猜您应该使用

#ifndef WIN32

instead of 代替

#if !WIN32

since the WIN32 macro not always exists, and you need to check for its existence rather than its "falseness". 因为WIN32宏并不总是存在,所以您需要检查它的存在而不是它的“错误”。

For question number two, is that line inside a header file? 对于第二个问题,该行是否位于头文件中? You should in general never define variables in headers, especially if that header is included in more than one file as that will create two copies of the same variable and will result in a link error. 通常,您永远不要在标头中定义变量,尤其是如果该标头包含在多个文件中,因为这将创建同一变量的两个副本并导致链接错误。

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

None of these reported errors are C++ errors; 这些报告的错误都不是C ++错误。 they're style issues. 他们是风格问题。

First: 第一:

#if !WIN32
#define ULONG_MAX 0xffffffff
#endif

This is legal. 这是合法的。 In a #if directive, any token that isn't defined is replaced by 0 . #if指令中,所有未定义的令牌都将替换为0 But it's probably better style to write #ifndef WIN32 , as others have already suggested. 但是编写#ifndef WIN32可能是更好的样式,正如其他人已经建议的那样。

But really, that whole thing is probably a bad idea. 但实际上,整个事情可能不是一个好主意。 ULONG_MAX is a macro defined in the C standard header <limits.h> , and the C++ standard header <climits> . ULONG_MAX是在C标准标头<limits.h>和C ++标准标头<climits>定义的宏。 Replace the above 3 lines by: 将以上3行替换为:

#include <climits>

Second: 第二:

const char CompanyName[] = "mycompany";

Legal, but a bad idea. 合法,但不明智。 If the header file is #include d from different translation units, you'll have multiple definitions of CompanyName . 如果头文件是来自不同翻译单元的#include d,则您将具有CompanyName多个定义。 (I'm not quite sure what the C++ rules say about that.) See Mysticial's answer. (我不太确定C ++规则对此有何看法。)请参见Mysticial的答案。

Third: 第三:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0;

Here PC-lint is being overly picky. PC-lint在这里过于挑剔。 Yes, the implicit conversion of 0 (which is of type int ) to unsigned long does change the signedness, but in this case it doesn't cause any possible problem. 是的,将0 (类型为int )隐式转换为unsigned long确实会改变有符号性,但是在这种情况下不会引起任何可能的问题。 But you can avoid the warning by using a literal of type unsigned long: 但是您可以通过使用unsigned long类型的文字来避免该警告:

unsigned long m_ClientThreadId; 
m_ClientThreadId        = 0UL;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM