C ++中的算术溢出添加2个DWORD

Posted

技术标签:

【中文标题】C ++中的算术溢出添加2个DWORD【英文标题】:Arithmetic overflow in C++ adding 2 DWORDs 【发布时间】:2019-12-06 05:26:32 【问题描述】:

我收到一个错误:

警告 C26451 算术溢出:对 4 字节值使用运算符“+”,然后将结果转换为 8 字节值。在调用运算符 '+' 之前将值转换为更宽的类型以避免溢出 (io.2)。

在以下代码中:

stream_name_offset + wsi->dwStreamNameSize <= wsi_buffer_size;

前两个是DWORDs,第三个是size_t

如何避免此警告?我尝试将 2 个字段的大小写为 size_t,但它仍然会产生警告。

【问题讨论】:

试试(0LLU + stream_name_offset + wsi-&gt;dwStreamNameSize) &lt;= wsi_buffer_size。这迫使 plus 的参与者成为更长的类型,并且应该正确地进行促销活动。 DWORD 是 32 位无符号的,0LLU 在加法期间强制提​​升为 64 位数学。 嗯,我无法复制这个。你确定给定的类型吗?您正在为 x64 构建,对吗?哪个版本的 Visual Studio? @SteveFriedl 最新的 2019 年,由于某种原因,当我重新启动 Visual Studio 时,当我再次尝试编译时它消失了,很奇怪。 编译器刚重启就消失了?我以为这种事情只发生在操作系统上。呵呵。 是的,转换其中一个操作数应该已经足够了,更不用说两者了,就可以让它正确了。当然,警告是正确的,并且所提供的代码对于足够大的流大小和偏移量是错误的。如果流参数只有 32 位宽但内容可能更大,那么程序的其余部分是否可以工作当然很难说 ;-)。 【参考方案1】:

在这种情况下,您必须在 sum 之前使用类似 c 的强制转换显式提升类型。你可以这样做:(unsigned long)stream_name_offset + (unsigned long)wsi-&gt;dwStreamNameSize &lt;= wsi_buffer_size;

另外一种情况,当表达式中有多个数据类型时,C++语言采用“Implicit Type Coversion”(类型提升),所以变量的所有数据类型都升级为变量的数据类型最大的数据类型。这是层次结构:

bool -> char -> short int -> int -> unsigned int -> long -> unsigned -> long long -> float -> double -> long double

使用隐式转换,当转换为无符号变量时,您必须注意有符号变量,符号将丢失。

【讨论】:

【参考方案2】:

我终于发现我做错了什么。感谢 Steve Friedl 和所有看过它的人。

事实证明,错误是我在运行编译的二进制文件时使用“在解决方案上运行代码分析”而不是“构建”引起的。

当这种情况发生时,Visual Studio 有一个奇怪的怪癖,它不断说你有同样的错误,即使你确实修改了文件。

当二进制文件停止运行时,将第一个参数封装到size_t 确实可以解决问题。为了安全起见,我将两者都投给了size_t

【讨论】:

以上是关于C ++中的算术溢出添加2个DWORD的主要内容,如果未能解决你的问题,请参考以下文章

C语言如何定义一个算术表达式

数据结构 栈的应用——算术表达式求值

40篇学完C语言——(第七篇)地址算术运算

shell中的算术运算

Python中的算术运算符都有哪些呢?

信息的表示和处理