简体   繁体   English

避免警告 C6386 的任何方法,无需完全禁用它或代码分析

[英]Any way to avoid warning C6386, without disabling it or Code Analysis altogether

Visual Studio 2019 started showing Code Analysis warnings as in-editor green squiggles by default.默认情况下,Visual Studio 2019 开始将代码分析警告显示为编辑器内的绿色波浪线。 These may be extremely useful for students learning C programming, because they catch classical mistakes, such as off by one array accesses.这些对于学习 C 编程的学生可能非常有用,因为它们可以捕获经典错误,例如一次数组访问。

Unfortunately false positives may completely ruin the learning experience and I fear that I will have to ask the students to disable the feature in order to avoid having them worry on non existing problems.不幸的是,误报可能会完全破坏学习体验,我担心我将不得不要求学生禁用该功能,以避免让他们担心不存在的问题。

This short snippet doesn't cause any warning:这个简短的片段不会引起任何警告:

#include <stdlib.h>

int main(void)
{
    size_t n = 6;
    int *v = malloc(n * sizeof(int));
    if (v == NULL) {
        return 1;
    }
    for (size_t i = 0; i < n; ++i) {
        v[i] = i;
    }
    free(v);
    return 0;
}

Unfortunately, if you move the allocation in a function, like this:不幸的是,如果您在函数中移动分配,如下所示:

#include <stdlib.h>

int *test(size_t n)
{
    int *v = malloc(n * sizeof(int));
    if (v == NULL) { 
        return NULL;
    }
    for (size_t i = 0; i < n; ++i) {
        v[i] = i;
    }
    return v;
}

int main(void)
{
    size_t n = 6;
    int *v = test(n);   
    free(v);
    return 0;
}

you get a warning C6386: Buffer overrun while writing to 'v': the writable size is 'n*sizeof(int)' bytes, but '8' bytes might be written.您会收到warning C6386: Buffer overrun while writing to 'v': the writable size is 'n*sizeof(int)' bytes, but '8' bytes might be written.

Even reading on Stack Overflow, I don't get where the '8' comes from, but, more importantly, why it fails to recognize that i will never be out of range.即使在 Stack Overflow 上阅读,我也不明白'8'是从哪里来的,但更重要的是,为什么它没有意识到i永远不会超出范围。

So the question is: is there a way to write this type of code in a way that will not generate the warning?所以问题是:有没有办法以不会产生警告的方式编写这种类型的代码?

I know that I can go to Tools > Options > Text Editor > C/C++ > Experimental > Code Analysis and set Disable Code Analysis Squiggles to True , or use a #pragma warning(disable:6386) , but I'd rather avoid it, and certainly avoid suggesting my students the latter.我知道我可以转到Tools > Options > Text Editor > C/C++ > Experimental > Code Analysis并将Disable Code Analysis Squiggles设置为True ,或者使用#pragma warning(disable:6386) ,但我宁愿避免它,当然要避免建议我的学生选择后者。

You can supress this warning (which could be considered a bug), simply by ensuring the value of n given to the malloc call has not "wrapped around" following overflow (as hinted at in the comment from Eric Postpischill ).您可以抑制此警告(这可以被视为错误),只需确保在溢出后给malloc调用的n值没有“环绕”(如Eric Postpischill评论中所暗示)。

To do this, you can replace the n argument by the seemingly bizarre max(n,0) :为此,您可以用看似奇怪的max(n,0)替换n参数:

int* test(size_t n)
{
//  int* v = malloc(n * sizeof(int));         // Warning C6386 on v[i] = i
    int* v = malloc(max(n, 0) * sizeof(int)); // No warning
    if (v == NULL) {
        return NULL;
    }
    for (size_t i = 0; i < n; ++i) {
        v[i] = i;
    }
    return v;
}

I really want to thank everybody for their contributions and I agree that it is a bug in the Code Analyzer (by looking on Microsoft web sites it has been "Closed - Lower Priority" two years ago...).我真的要感谢大家的贡献,我同意这是代码分析器中的一个错误(通过查看 Microsoft 网站,两年前它已被“关闭 - 低优先级”......)。

Adrian Mole max(n, 0) trick points to a way for coping with the warning in code, that is checking that n is greater than zero. Adrian Mole max(n, 0)技巧指出了一种处理代码警告的方法,即检查n是否大于零。 The funny thing is that you can still use that zero for what n was supposed to be used.有趣的是,您仍然可以将零用于应该使用的n While the idea could be used for experienced programmers (that would probably disable the warning), as John Bollinger points out, it's not for students.虽然这个想法可以用于有经验的程序员(这可能会禁用警告),但正如 John Bollinger 指出的那样,它不适用于学生。

So, after telling the students that it's a bug and how to turn off the Code Analysis squiggles or disable the warning, I'd go with所以,在告诉学生这是一个错误以及如何关闭代码分析曲线或禁用警告后,我会去

int *test(size_t n)
{
    if (n == 0) {
        return NULL;
    }
    int *v = malloc(n * sizeof(int));
    if (v == NULL) {
        return NULL;
    }
    for (size_t i = 0; i < n; ++i) {
        v[i] = i;
    }
    return v;
}

Which may also be interpreted as: don't allow 0 elements allocation.这也可以解释为:不允许 0 个元素分配。

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

相关问题 为什么这段代码会触发MSVS2012的“写入溢出警告(C6386)” - Why is this piece of code triggering “Write overrun warning (C6386)” with MSVS2012 我该如何解决这个警告 C6386 - How can i solve this warning C6386 c6386 写入时缓冲区溢出 - c6386 buffer overrun while writing C6386 - 使用 fread() 函数写入“缓冲​​区”时缓冲区溢出 - C6386 - Buffer overrun while writing to 'buffer' when using fread() function 如何通过静态分析检测巨大C代码中的内存泄漏(不使用任何工具) - How to detect memory leak in huge C code by static analysis(without using any tool) Visual Studio代码分析显示警告C6054 - Visual Studio Code Analysis shows Warning C6054 连同库实现一起获取预处理的C代码 - Get preprocessed C code altogether with library implementation 如何在CDT(C代码)中逐行关闭静态代码分析警告? - How do I turn off a static code analysis warning on a line by line warning in CDT (C code)? 有没有其他方法可以避免 TIme Limit Exceeded 或简化给定的代码? - Is there any other way to avoid TIme Limit Exceeded or simplify the given code? 使用__attribute __((弱))导致警告“冗余重新声明xxx”,有什么办法可以避免? - using __attribute__ ((weak)) leads to warning “redundant redeclaration of xxx”, any way to avoid?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM