警告 C26454: 编译时算术溢出:'-' 操作导致负无符号结果 (io.5)

9

代码分析:

ON_NOTIFY(TCN_SELCHANGE, IDC_TAB_HISTORY_TYPE,
  &CAssignHistoryDlg::OnTcnSelchangeTabHistoryType)

警告 C26454:

算术溢出:'-' 操作在编译时产生负无符号结果 (io.5)。

TCN_SELCHANGE 的定义如下:

#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

我不知道还能做什么!


2
事实上,我经常遇到这些错误。以前从未出现过这种情况。因此,在VC中发生了一些变化。 - Andrew Truckle
4
他们应该使用#define TCN_FIRST 0xFFFFFDDA而不是试图过于花哨。您可以重新定义常量(这并不总是一个好主意),或者使用#pragma warning push/pop来隐藏警告。 - Barmak Shemirani
1
FYI:https://developercommunity.visualstudio.com/content/problem/285656/warning-c26454-arithmetic-overflow-operation-produ.html - Andrew Truckle
3
您应在提交中说明这是一个“代码分析警告”,而不是编译器警告。 - Barmak Shemirani
3
这里的讽刺之处在于,这可能是由于有人试图使这些常量在警告级别4下静默编译的结果。如果将TCN_FIRST定义为-550U,则会得到一个编译时警告(因为对无符号值应用一元减运算是可疑的)。 - Adrian McCarthy
3个回答

8
//windows header file:
#define TCN_FIRST (0U-550U)
#define TCN_SELCHANGE           (TCN_FIRST - 1)

//user file:
...
unsigned int i = TCN_SELCHANGE;

以上代码在C++中是有效的,应该可以编译而不会有任何警告。没有溢出,那只是意味着 -550U。如果他们写成 #define TCN_FIRST 0xFFFFFDDA0xFFFFFFFFU-549U,会更清晰明了。

代码分析似乎使用了不同的方法并看到了溢出。

可能的解决方案:

在代码中禁用警告:

#pragma warning( push )
#pragma warning( disable : 26454 )

BEGIN_MESSAGE_MAP(CMyDialog, CDialogEx)
    ON_NOTIFY(TCN_SELCHANGE, IDC_TAB1, OnTcnSelchangeTabHistoryType)
END_MESSAGE_MAP()

#pragma warning( pop )

或者,禁用代码分析规则中的警告
使用代码分析规则集编辑器

enter image description here


我没有配置菜单项。 - Andrew Truckle
1
这个链接很有帮助:https://learn.microsoft.com/en-gb/visualstudio/code-quality/how-to-create-a-custom-rule-set。我需要右键单击项目并进入属性,通过这种方式才能找到它。 - Andrew Truckle
它有效。在我的情况下,仍然显示从未使用过的其他代码是:C264XX 34、39、51和95。 - Andrew Truckle
无论哪种方式,都会变得有点混乱。如果微软能够找到一个解决方法,而不是完全禁用警告,那就太好了。 - Barmak Shemirani
1
我同意。他们提出了不应该提出的问题。特别是当涉及到他们自己的代码时。就像我的另一个问题,其中一个方法调用了基类,然后基类方法没有被隐藏,因为它已经被明确调用了。 - Andrew Truckle

2
你正在尝试从一个较小的无符号值中减去一个较大的无符号值,导致结果超过了零。在你的情况下,我假设TCN_FIRST被定义为0,因此将TCN_SELCHANGE设置为1将解决这个问题。
无论如何,你应该使用constexprconst而不是定义。
根据MSDN: C++ Core Check中的算术溢出检查

C26451 RESULT_OF_ARITHMETIC_OPERATION_CAST_TO_LARGER_SIZE : [operator]操作超过0并在编译时产生一个大的无符号数。此警告表示减法操作产生了一个负数结果,在无符号上下文中进行了评估。这导致结果超过0并产生一个非常大的无符号数,可能会导致意外的溢出。

1 // Example source:
2 unsigned int negativeunsigned() {
3    const unsigned int x = 1u - 2u; // C26454 reported here
4    return x;
5 }

1 // Corrected source:
2 unsigned int negativeunsigned() {
3     const unsigned int x = 4294967295; // OK
4     return x;
5 }

在更正后的源代码中,无符号结果被赋予了一个正值。

1
但这些不是我的定义,它们是微软的定义。 - Andrew Truckle
它们是常见控制头的一部分:#define TCN_FIRST (0U-550U) - Andrew Truckle

0

我刚开始使用MFC对话框,当使用TVN_SELCHANGED时(它生成0-58U),我遇到了与上述相同的问题,这是由以下代码引起的:

#define TVN_SELCHANGEDW (TVN_FIRST-51) 可在Microsoftcommctrl.h中找到。

然而,这并不会导致程序编译失败。我认为,防止该错误消息可能会导致其他麻烦,如果实际的数学运算确实存在问题。我想重新定义常量可能是一个(稍微)更好的方法(提供一个良好的注释以供将来参考),除非您正在使用大量这些常量。


我没有改变任何MFC定义常量的意图。这是我必须面对的事情。更新SDK以具有更合适的值取决于微软。但我们现在已经谈论了5年,所以我怀疑这一点。 - Andrew Truckle
我也在我的问题中作为注释提到了相同的定义。 - Andrew Truckle

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接