- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下一段 C 代码:
#include <stdint.h>
typedef union{
uint8_t c[4];
uint16_t s[2];
uint32_t l;
}U4;
uint32_t cborder32(uint32_t l)
{
U4 mask,res;
unsigned char* p = (unsigned char*)&l;
mask.l = 0x00010203;
res.c[(uint8_t)(mask.c[0])] = (uint8_t)p[0]; // <-- this line gives C6386
res.c[(uint8_t)(mask.c[1])] = (uint8_t)p[1];
res.c[(uint8_t)(mask.c[2])] = (uint8_t)p[2];
res.c[(uint8_t)(mask.c[3])] = (uint8_t)p[3];
return res.l;
}
并且在对其运行代码分析时会触发写入溢出警告。 http://msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k%28C6386%29&rd=true
错误是:
C6386 写入“res.c”时缓冲区溢出:可写大小为“4”字节,但可能写入“66052”字节。对 'res.c[66051]' 的写入无效,(可写范围为 0 到 3)
我只是不明白为什么......有没有人可以向我解释为什么?
最佳答案
我将其记为 Microsoft 产品中的一个潜在错误。它似乎在计算数组索引时使用了 mask.l
的完整值(0x01020304
是十进制 66051
),尽管事实上你显然希望将 mask.c[0]
强制为 uint8_t
值。
所以第一步是通知微软。他们可能回来告诉你你错了,并希望给你 C++ 标准部分,说明为什么你所做的是错误的。或者他们可能只是说代码分析工具是“尽力而为”。由于它实际上并没有阻止您进行编译(并且在编译过程中不会产生错误或警告),他们仍然可以声称 VC++ 是兼容的。
当然,我希望他们不会采取这种策略,因为他们非常有兴趣确保他们的工具是最好的。
您应该采取的第二步骤是首先质疑您为什么要以那种方式做您正在做的事情。您所拥有的似乎是一个基于掩码的简单字节顺序切换器。声明:
res.c[(uint8_t)(mask.c[0])] = (uint8_t)p[0];
无论如何都是有问题的,因为 (uint8_t)(mask.c[0])
很可能会计算出大于 3 的值,并且您将在 union 结束后写入案例。
您可能认为确保mask
没有大于3
的字节可能会阻止这种情况,但分析器可能不知道这个。无论如何,已经有很多方法可以切换字节顺序,例如使用 htons
函数系列,或者由于您的内容无论如何都是硬编码的,只需使用以下方法之一:
res.c[0] = p[0]; res.c[1] = p[1]; res.c[2] = p[2]; res.c[3] = p[3];
或:
res.c[0] = p[3]; res.c[1] = p[2]; res.c[2] = p[1]; res.c[3] = p[0];
或其他东西,用于奇怪的字节排序要求。使用此方法根本不会引起分析仪的任何投诉。
如果您真的想要使用当前的mask
方法来完成它,您可以删除分析器警告(至少在我正在使用的 VS2013 中)暂时压制它(一行):
#pragma warning(suppress : 6386)
res.c[mask.c[0]] = p[0];
res.c[mask.c[1]] = p[1];
res.c[mask.c[2]] = p[2];
res.c[mask.c[3]] = p[3];
(由于类型已经正确,因此删除了强制转换)。
关于c - 为什么这段代码用 MSVS2012 触发 "Write overrun warning (C6386)",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22592110/
我们有 50 多个项目,分为由 TFS 管理的 2 个解决方案树(版本:Visual Studio 2008/TFS RTM (9.0.21022.8))。 30 多个项目是 Visual Studi
我尝试将预构建的 Qt 二进制文件用于 MSVS 2008 和 MSVS 2010。(没有用于 MSVS 2010 的预构建二进制文件。) 这适用于发布版本,但对于调试版本,我的 Qt 应用程序无法启
我在 MSVS 2010 中有一个 MFC 项目。当我编译它时,MSVS 生成包含以下行的 list 文件: 因此,我得到一个二进制文件,它依赖于 MSVS 2008 的 vcredist_x86.
安装 MSVS 11Beta 后,我的 MSVS 10 遇到了编译问题。现在,当我在 MSVS 10 中编译我的 C# 项目时(在 MSVS 10 中创建的项目;目标框架:3.5),出现错误 MSB4
我有一个项目在 MSVS 2010 SP1 下运行良好。我正在尝试将其转换为 MSVS 2012 RC。我不得不更改一些内容,主要与 C++ header /lib 路径和 MFC 自定义内容有关。但
我正在查看由 msvs 2008 链接器生成的可执行文件中的数据部分,我发现它在常量静态字符串之间插入了某种标记: 我查看了其他几个可执行文件,发现了相同的模式。实际字节值虽然不同,但仍插入字符串之间
#include "hmap.h" int main(char* argv[], int argc) { printf("%s", argv[0]); <---- fails here
我正在寻找一个简单的工具,它接受路径、扫描文件夹并创建包含所有找到的项目的解决方案 (sln) 文件。 自动设置项目依赖项对我来说是该工具的一大优势。 我知道写这个东西很简单,但一定有很多“小 hel
我要执行以下操作: 使用MSVS 2015 IDE构建检测的PGO exe 将生成的exe及其.pgd文件复制到其他几台计算机 在这些计算机上从命令行运行exe。请注意,这些计算机上没有MSVS编译器
我按照此处的说明操作 How to create and use resources in .NET 但是当我执行 Properties.Resources.Name;我收到“当前上下文中不存在名称‘
我正在编写一些应该将 Eigen::Array 作为输入的函数。数组的大小不变,但大小是模板参数,应从输入中扣除。使用 MSVS 编译时,我必须为函数提供大小,否则会导致错误。 #include t
前一段时间,这个question被问到,关于熟悉的 error: 'static' can only be specified inside the class definition 错误。 在我当前
虽然增量链接解决了花费在链接上的大部分时间,即使对于非常大的项目,我发现 MSVS 中的增量链接器非常随意。 (我目前正在使用 2003 atm,很想知道 2005/8 是否解决了这些问题。)我的已知
我的代码是在 MSVS 2013 的某些平台和 MSVS 2010 的其他平台上编译的(更不用说 UNIX 和 VMS)。由于 MSVS 2010 不支持语句后的声明(如 “weird-compila
我想创建一个将消息映射到默认处理器的编译时结构,但我的代码无法在 msvs 2015 update2 中编译。我认为这是编译器中的一个错误,因为代码非常合法并且可以使用 gcc 进行编译。您可以在下面
我在程序中某处调用以下函数会抛出异常 public static List LoadTemplates() { // ... // System.Threading.Thread.Cu
用_Check_return_注释函数的正确方法是什么? 在以下示例中,静态分析器只产生一个警告而不是两个: _Check_return_ int foo() { return 42; } _
在处理 Windows API 时,我试图通过替换两行代码来使我的代码不那么臃肿 TEMP t{0,1,2}; // let's say it's struct TEMP {int a; int b;
我最近一直忙于为我一直在设计的代码库制作正确的构建脚本,并且一直致力于让 MSBuild 为我的 Windows 构建正确编译。我想要做的是从批处理脚本中调用 MSBuild 而无需打开 Visual
我已尝试阅读所有我能找到的似乎适用于我的代码的链接器错误,但我还没有找到解决方案,因此非常感谢您的帮助。从我读过的内容来看,链接器错误似乎适用于我的代码的唯一原因是声明/定义不匹配,因为它之前工作正常
我是一名优秀的程序员,十分优秀!