📜 ⬆️ ⬇️

So you want to silence this warning in Visual C ++ ...

FAIL The usual situation: you wrote a piece of impeccably correct code, but Visual C ++ issues a warning on it. Often, you can rewrite the code a bit so that the warning is gone, but not always, and then the only way out is to turn off the warning.

Consider what opportunities for this are in Visual C ++ and what errors make when using them.


')
The most obvious first possibility is to disable the warning in the project settings at the project level . It works, but badly. First, the warning will be drowned out in the whole project, including all the headings that this project includes. Secondly, if you copy the code into another project, a warning will appear again. This will inevitably occur in the case of code in the header files (for example, containing the implementation of templates), which must be included (#include) in each project that uses them.

The next option is to disable the warning in the project settings at the file level . This method is even worse than the previous one. First, the warning will be silenced for the entire broadcast unit, i.e. in this file and all the headers that it includes. Secondly, exactly the same problems with copying the code as last time. Third, as soon as a project has more than a few files, the probability of losing this setting when a project is converted to a newer version of Visual C ++ becomes slightly less than one.

Remains use of #pragma warning. Usually it is used as follows:

 #pragma warning (disable: 9000) // ,   C9000 #pragma warning (default: 9000) 

... and remain very pleased with themselves. The warning was muffled, the code was written, the warning was restored. Profit.

Actually, this is FAIL. It's time to read carefully (yes, carefully and yes, read, and not copy-paste code from anywhere) the description of #pragma warning (default). It says the following: this construction

1. sets the default warning level and
2. includes a warning.

First levels. In Visual C ++, a number from 1 to 4 is associated with each warning — this is the warning level. Level 1 warnings are considered more serious, with an increase in severity level ostensibly decreases. Each alert has a default level. Design

 #pragma warning(Level: Warning) 

sets the warning level indicated in it and includes a warning, i.e. the level is not nailed, you can change it.

The compiler has a setting, from which warning level to show, Warning Level . If this setting is set to A, a warning in a specific line of code is shown only if it is allowed there and its level is A or lower.

In addition, in Visual C ++, some of the warnings are turned off by default, because they are issued even in the most innocuous code and everyone is tired of them. Let everyone who is going to rebel against the very idea of ​​pinpoint suppression of a specific warning, be aware of and experience this fact to begin with.

Consider how FAIL appears when using #pragma warning (default).

FAIL 1 . Warning C9001 is disabled by default. The code in the header file uses #pragma warning (default: 9001) to “restore” the warning, muffled in a small piece of code.

Why does he do this if the warning is already off? The list of warnings that are turned off by default changes from one version of Visual C ++ to another — warnings are gradually added to it. If the code was originally written for Visual C ++ 7, and there C9001 was enabled by default, and now they are compiled in Visual C ++ 10, and the warning is already turned off, then this construction has no meaning, but could simply be inherited.

As a result, #pragma warning (default) forces a warning to be turned off by default.

FAIL 2 . Warning C9002 has a default level of 3, and the project is compiled with level 2, i.e. "Show warnings level 2 and below." After much thought, the developers decided that in fact the C9002 warning was serious enough to honor its level 2, i.e. forcibly raise the seriousness. Accordingly, each project includes a standard header, which then falls into all translation units, which contains the #pragma warning (2: 9002) construct.

Slightly lower in the translation unit is #pragma warning (default: 9002), which resets the level back to 3, and when compiled with level 2 a warning is not issued. Incidentally, this warning reported a serious defect. Smile and wave. In the opposite direction, it also works - the warning was “raised” level from 2 to 3, so that it would not be issued in projects compiled with levels 2 and below (i.e. lowered severity), but #pragma warning (default) resets the level to 2, and a warning is issued.

FAIL 3 . The C9003 warning is enabled by default, but thought out so badly that no one can remember when it is issued on a case. Developers decide to drown it everywhere by using #pragma warning (disable: 9003) in the common header file. The lower unit of translation is #pragma warning (default: 9003), which includes a warning.

What is especially nice is that these situations arise at the most opportune moment - when switching from one version of the compiler to another, when you try to include a bunch of third-party code in the project, which is already not easy to use, the second situation simply leads to suppression of the warning, as a result miss an error in the code, which later will help users get Darwin Award.

In fact, warnings should be silenced as follows:

 #pragma warning(push) // ,  : www.abbyy.ru/vacancy #pragma warning(disable:9000) //    C9000 #pragma warning(pop) 

The first construction saves the current state of the alert settings, the second one disables the required warning, the third one restores the saved state. In this case, the state is restored completely - all changes made by the levels above are also restored, warnings that are turned off by default are not included.

It looks scary, but what you will not do, so as not to miss the very same mistake for a billion.

Dmitry Mescheryakov,

product department for developers

Source: https://habr.com/ru/post/136909/


All Articles