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;
前两个是DWORD
s,第三个是size_t
。
如何避免此警告?我尝试将 2 个字段的大小写为 size_t
,但它仍然会产生警告。
【问题讨论】:
试试(0LLU + stream_name_offset + wsi->dwStreamNameSize) <= 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->dwStreamNameSize <= 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的主要内容,如果未能解决你的问题,请参考以下文章