问题描述
默认情况下,Visual Studio 2019开始将代码分析警告显示为编辑器内的绿色花键。这些对于学习C编程的学生可能非常有用,因为它们会捕获经典错误,例如被一个数组访问所抵消。
不幸的是,误报可能会完全破坏学习体验,并且我担心我将不得不要求学生禁用该功能,以避免让他们担心不存在的问题。
此简短代码段不会引起任何警告:
#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;
}
不幸的是,如果您在函数中移动分配,如下所示:
#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;
}
您得到一个warning C6386: Buffer overrun while writing to 'v': the writable size is 'n*sizeof(int)' bytes,but '8' bytes might be written.
即使阅读了Stack Overflow,我也不知道'8'
的来源,但更重要的是,为什么它无法识别i
永远不会超出范围。
所以问题是:有没有办法以不会产生警告的方式编写此类代码?
我知道我可以转到Tools > Options > Text Editor > C/C++ > Experimental > Code Analysis
并将Disable Code Analysis Squiggles
设置为True
,或使用#pragma warning(disable:6386)
,但我宁愿避免使用它,并且一定要避免建议我的学生是后者。
解决方法
我真的想感谢大家的贡献,我也同意it is a bug in the Code Analyzer(通过两年前在Microsoft网站上查看,该网站处于“关闭-优先级较低” ...)。
Adrian Mole max(n,0)
技巧指出了一种处理代码中警告的方法,即检查n
是否大于零。有趣的是,对于应该使用的n
,您仍然可以使用该零。正如约翰·博林格(John Bollinger)指出的那样,虽然这个想法可以用于有经验的程序员(这可能会禁用警告),但它不适用于学生。
因此,在告诉学生这是一个错误以及如何关闭代码分析曲线图或禁用警告之后,我会同意
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;
}
也可以解释为:不允许分配0个元素。