2

在我公司的代码中,我们有通用的 get() 和 set() 方法用于某些组件之间的互操作。但是,如果我尝试运行 PREfast,我会被警告淹没,因为 PREfast 没有意识到 get() 方法初始化了给定的参数。

问题是,由于这些方法非常通用,它们不简单地接受一个参数(我可以用_Out_或类似的标记,而是一个结构数组,其中包含应该返回哪些数据的数据。

在代码中(大大简化):

typedef struct
{
    int type;
    int* data;
} ARGS;

void get(int count, ARGS* args)
{
    for (int i = 0; i < count; i++)
        *(args[i].data) = 42; // Actually handled by internal methods
}

// Sample Usage
void foo()
{
    int value;
    ARGS args[1];

    args[0].type = 1234;
    args[0].data = &value;

    get(1, args);

    // Do something with value
    // PREfast complains that value is uninitialized (error C6001)
    printf("%d", value);
}

有什么方法可以对此进行注释,以便 PREfast 知道它args.data是由 初始化的get()吗?还是这对于 PREfast 来说太复杂了?

编辑:如果我使用get(1, &args),那么警告就会消失。所以PREfast中有一些启发式可以处理这种情况,但我还没有发现是否可以从外部触发它:

void get2(int count, ARGS(* args)[1]) // Needs the size of args, or it won't compile below
{
    for (int i = 0; i < count; i++)
        *(*args)[i].data = 42; // Actually handled by internal methods
}

// Sample Usage
void foo2()
{
    int value;
    ARGS args[1];

    args[0].type = 1234;
    args[0].data = &value;

    get2(1, &args);

    // Do something with value
    printf("%d", value);
}
4

1 回答 1

1

This should fix the warning.

void foo()
{
   int value=0;
  ...
}

Note that get() will be called in runtime only. Since, PREfast is a static analysis tool, it might report that the value is uninitialized. Nevertheless, initializing a variable before use is always a best practice in C.

Another way would be to use the PREfast suppress as below:

void foo()
{
    int value;
    ARGS args[1];

    args[0].type = 1234;
    args[0].data = &value;

    get(1, args);

    // Do something with value
    // PREfast complains that value is uninitialized (error C6001)
    #pragma prefast(suppress:C6001 , "PREfast noise: the variable value will be initialized by get method in a line above")
    printf("%d", value);
}

It suppresses the warnings in the next line after the suppress statement.

Also, do add the following code in you header files(or source files) just before using the pragma prefast in your code:

#ifndef _PREFAST_
#pragma warning(disable:4068)
#endif

to avoid 4068 warning to be flagged. NOTE: pragma prefast is an extension to the PREfast AST compiler only and may not be supported by other compilers.

于 2012-10-18T20:36:01.087 回答