Share via


Using a Pragma Warning Directive

You can permit and suppress particular PREfast for Drivers warnings by including a pragma warning directive in your source code. Unlike filters that temporarily change the appearance of a Defect Log, the pragmas are applied during the PREfast for Drivers analysis and change the result.

For a description of the warning pragma, see warning in the C/C++ Language Reference.

When using a pragma warning directive, use the identification numbers of the PREfast for Drivers warnings as the elements in the warning-number-list. For example:

#pragma warning( disable : 28100 28101) 

Example: Using a Pragma Warning Directive

In the following example, PREfast for Drivers is reporting Warning 6001 on the first use of the variable i after the FOR loop. The i is initialized in the FOR loop, but PREfast for Drivers recognizes that the loop might never be executed.

extern int arr[];
extern arrSize;
#define FLAG 10

void f()
{
    int i, j;

    int c;
    // Find the entry in arr that contains FLAG
    for (c=0; c<arrSize; c++)
    {
        if (arr[c] == FLAG)
        {
            i = c;
        }
    }

    arr[i+1] = 0;  // Warning 6001 is reported
    j++;
}

If you are certain that there is always at least one instance of FLAG in the arr array, you can suppress the warning. The easiest way to suppress the warning is to initialize i outside of the loop or use an ASSERT macro. However, you can also use a pragma warning directive.

The following example shows the correct use of the pragma warning directive to suppress the 6001 warning. The (push) and (pop) statements are included to confine the effect of the pragma to the line of code in which i is used. Without the (push) and (pop) statements, the pragma would also suppress any instances of Warning 6001 on all subsequent statements in the function, including the next line of code in which the variable j is used without being initialized.

Notice that the pragma warning directive is accompanied by a comment that explains why the warning is suppressed. This "best practice" helps to ensure that if the code changes and the reason is no longer valid, you will recognize the effect and remove the pragma.

extern int arr[];
extern arrSize;
#define FLAG 10

void f()
{
    int i, j;

    int c;
    // Find the entry in arr that contains FLAG
    for (c=0; c<arrSize; c++)
    {
        if (arr[c] == FLAG)
        {
            i = c;
        }
    }

#pragma warning (push)
#pragma warning( disable:6001 ) // FLAG is always present in arr
    arr[i+1] = 0;
#pragma warning (pop)
    j++; // Warning 6001: Actual error
}

The Suppress Warning Specifier

You can also use the suppress warning specifier with a pragma warning directive. A pragma warning directive with the suppress specifier suppresses the warning only for the line of code that immediately follows the #pragma warning statement.

The syntax for the suppress warning specifier is as follows:

#pragma warning( suppress : warning-number ) 

For example, in the following code, the warning pragma suppresses Warning 6001 on the arr[i+1] = 0; statement, but it does not suppress Warning 6001 on the j++; statement, or any statement thereafter.

#pragma warning( suppress : 6001 ) 

arr[i+1] = 0; // Warning 6001 is suppressed

j++; // Warning 6001 is reported

}

The suppress specifier suppresses warnings 6000-7999, 20000-40000 and some, but not all, compiler errors (warnings < 6000).

Note  If the #pragma warning directive with the suppress warning specifier does not suppress the warning, it might be because the particular warning applies to the function body as a whole, not its individual statements. To suppress warnings of this type, such as Warning 28195, place the #pragma warning directive on the line immediately preceding the first brace ({) of the function body.

Defining a PREFAST_SUPPRESS Macro

You can define a PREFAST_SUPPRESS macro that uses the warning pragma. This macro uses __pragma, because #pragma cannot be used in a macro.

For example, the following PREFAST_SUPPRESS macro implements the functionality of the warning pragma.

#define PREFAST_SUPPRESS(n, stmt) __pragma(warning(push)) __pragma(warning(disable:n)) stmt __pragma(warning(pop))

When the macro is called, the statement that is protected from the warning must be included in the call in its entirety, including the final semicolon. For example:

PREFAST_SUPPRESS(6001, arr[i+1] = 0;)

You can also define a macro that uses the suppress warning specifier. For example:

#define PREFAST_SUPPRESS(n, stmt) __pragma(warning(suppress:n)) stmt

The call to this macro must be followed by a blank line, because the macro will suppress any instance of the error on the line immediately following the macro, as well as suppress the warning for the statement in the macro. This form of suppression is particularly useful when the undesired warning is being reported from within a macro.

Use of pragma warning as a recursion breaker.

The warning pragma can also be used to suppress PREfast for Drivers warnings about functions that PREfast for Drivers cannot interpret correctly, even though they are coded correctly and operate correctly.

One class of commonly misinterpreted functions is those that actually perform a specific task such as: allocating memory, acquiring a lock, or entering a critical region, as opposed to those that call other functions to do the work. Because PREfast for Drivers cannot follow the complex pointer arithmetic that is used in the implementation, it often reports that the function did not complete its task, such as by reporting 28195 -The current function was declared as acquiring memory in <variable> and exited without doing so. After verifying that the function performs the task correctly, you can use a warning #pragma to suppress the warning (note that, the #pragma should be placed on the line just before the '{' that begins the function).

 

 

Send comments about this topic to Microsoft

Build date: 5/3/2011