153

Is there a way to disable just a single warning line in a cpp file with visual studio?

For example, if I catch an exception and don't handle it, I get error 4101 (unreferenced local variable). Is there a way to ignore this just in that function, but otherwise report it in the compilation unit? At the moment, I put #pragma warning (disable : 4101) at the top of the file, but that obviously just turns it off for the whole unit.

Sam
  • 7,252
  • 16
  • 46
  • 65
Cookie
  • 12,004
  • 13
  • 54
  • 83
  • 22
    if you mention only the type and don't name the exception, there will be no warning. E.g. `catch (const std::exception& /* unnamed */) {.... }`. It doesn't answer your question, but might solve your problem. – Sjoerd Aug 23 '11 at 10:10
  • 1
    Google searches for **"how to suppress -Wunused-result in c++"** lead here, so here's the answer to for just that specific case: https://stackoverflow.com/a/63512122/4561887. – Gabriel Staples Aug 20 '20 at 20:13

11 Answers11

213
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 
Andreas Brinck
  • 51,293
  • 14
  • 84
  • 114
  • 1
    @Cookie: yes, it works for any piece of code that go through the compiler. – Matteo Italia Aug 23 '11 at 10:22
  • For a more recent, concise answer, see Daniel Seither's answer, below. – Dan Nissenbaum Jun 13 '16 at 20:45
  • 4
    `clang` doesn't seem to support this pragma, but you can achieve the same effect with `#pragma clang diagnostic push`, `#pragma clang diagnostic ignored "-Wunused-variable"`, and `#pragma clang diagnostic pop`. See ["Controlling Diagnositics Via Pragmas" in the Clang User's Manual](http://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas) – rampion Aug 31 '16 at 14:44
  • Since I use this feature infrequently, when I do so, I usually wind up on this page to remind myself of the syntax. I just put it around a call to a deprecated function that may never get updated, so that the warning won't annoy me in the compiler listings, which I scan religiously. – David A. Gray Dec 04 '16 at 07:07
  • For Visual Studio, the command line argument is `/wd4101`. Note there is not the normal `:` between the flag and the number, and you can't do a comma separated list of numbers. For other compilers it _might_ be `/nowarn:4101` instead. – Jesse Chisholm May 24 '17 at 18:15
  • Is there a compiler agnostic way to do this? (gcc, VS, clang, ...)? – wcochran Mar 20 '20 at 16:45
132

If you only want to suppress a warning in a single line of code (after preprocessing)[1], you can use the suppress warning specifier:

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

For a single line of code, this works the same as writing the following:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)

[1] Others have noted in comments below that if the following statement is an #include statement that the #pragma warning(suppress: 4101) statement would not effectively suppress the warning for every line in the header file. If one were intending to do that, one would need to utilize the push/disable/pop method instead.

beevis
  • 73
  • 1
  • 7
Daniel Seither
  • 1,647
  • 1
  • 13
  • 19
  • 10
    Very useful! Unfortunately, it does not work for a single line that includes a header which generates the warning. – Marko Popovic Mar 01 '16 at 11:02
  • 4
    @MarkoPopovic: The `suppress` specifier operates on a single, **pre-processed** line of code. If the line following `#pragma warning(suppress: ...)` is an `#include` directive (which expands the file referenced by its parameter into the current compilation unit), the effect applies to the first line of that file only. This should be obvious, since warnings are generated by the compiler. The compiler operates on pre-processed code. – IInspectable Dec 19 '16 at 11:49
  • @IInspectable In that case I'd call it a *post-processed* line of code. *pre-processed* means it hasn't been translated by the preprocessor yet. – void.pointer Sep 17 '19 at 16:04
  • 2
    @voi: The *"-ed"* ending signifies the [past participle](https://en.wikipedia.org/wiki/Participle). It is used to express, that something has ended in the past. A *"pre-processed"* line is a line that has been fully processed. – IInspectable Nov 02 '19 at 12:42
  • these comments confused me a little, if anyone falls in the same boat, what they mean is `#pragma warning(suppress: 4101)` \n `#include "wholeFile.h` won't suppress errors in the whole header (obviously, but comments usually point at unobvious behavior, thus the confusion) You can use this within the header itself no prob – Anne Quinn Aug 03 '21 at 13:46
30

#pragma push/pop are often a solution for this kind of problems, but in this case why don't you just remove the unreferenced variable?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}
Matteo Italia
  • 123,740
  • 17
  • 206
  • 299
  • 6
    This is not an aswer to the question. Granted, this might solve OP's problem, but won't help future readers with a simular question: "how do I turn off a specific warning for a specific part of my code?" – Sjoerd Aug 23 '11 at 10:16
  • 1
    @Sjoerd: three people already answered the "official question" that other people may search, so instead I tried to read between the lines and solve his actual problem (arriving one minute after your comment `:P`). – Matteo Italia Aug 23 '11 at 10:18
  • 15
    @Sjoerd as a future reader I attest that this answer in fact did help me. – Mołot Jul 07 '15 at 11:31
  • 2
    @Mołot: as a past writer, I'm glad it helped. =) – Matteo Italia Jul 07 '15 at 11:38
  • 10 years after and, I am still not using exceptions... Very often I compile with the (cl.exe) `/kernel` switch. – Chef Gladiator Mar 21 '21 at 09:58
11

Example:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

This pragma is valid for C++ starting with Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

The pragma is NOT valid for C# through Visual Studio 2005 through Visual Studio 2015.
Error: "Expected disable or restore".
(I guess they never got around to implementing suppress ...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C# needs a different format. It would look like this (but not work):

#pragma warning suppress 0642  // (suppress one error in the next line)

Instead of suppress, you have to disable and enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

That is SO ugly, I think it is smarter to just re-style it:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else
A876
  • 471
  • 5
  • 8
9

Use #pragma warning ( push ), then #pragma warning ( disable ), then put your code, then use #pragma warning ( pop ) as described here:

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 
Community
  • 1
  • 1
sharptooth
  • 167,383
  • 100
  • 513
  • 979
  • How do you get warning code? I have this warning: `expression must have a constant value C/C++(28)`. But putting warning code as 28 didn't work!. – Sourav Kannantha B Dec 28 '21 at 17:40
8

as @rampion mentioned, if you are in clang gcc, the warnings are by name, not number, and you'll need to do:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

this info comes from here

orion elenzil
  • 4,484
  • 3
  • 37
  • 49
6

One may also use UNREFERENCED_PARAMETER defined in WinNT.H. The definition is just:

#define UNREFERENCED_PARAMETER(P)          (P)

And use it like:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Why would you use it, you might argue that you can just omit the variable name itself. Well, there are cases (different project configuration, Debug/Release builds) where the variable might actually be used. In another configuration that variable stands unused (and hence the warning).

Some static code analysis may still give warning for this non-nonsensical statement (wParam;). In that case, you mayuse DBG_UNREFERENCED_PARAMETER which is same as UNREFERENCED_PARAMETER in debug builds, and does P=P in release build.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)
Ajay
  • 18,086
  • 12
  • 59
  • 105
5

This question comes up as one of the top 3 hits for the Google search for "how to suppress -Wunused-result in c++", so I'm adding this answer here since I figured it out and want to help the next person.

In case your warning/error is -Wunused (or one of its sub-errors) or -Wunused -Werror only, the solution is to cast to void:

For -Wunused or one of its sub-errors only1, you can just cast it to void to disable the warning. This should work for any compiler and any IDE for both C and C++.

1Note 1: see gcc documentation here, for example, for a list of these warnings: https://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html, then search for the phrase "All the above -Wunused options combined" and look there for the main -Wunused warning and above it for its sub-warnings. The sub-warnings that -Wunused contains include:

  • -Wunused-but-set-parameter
  • -Wunused-but-set-variable
  • -Wunused-function
  • -Wunused-label
  • -Wunused-local-typedefs
  • -Wunused-parameter
  • -Wno-unused-result
  • -Wunused-variable
  • -Wunused-const-variable
  • -Wunused-const-variable=n
  • -Wunused-value
  • -Wunused = contains all of the above -Wunused options combined

Example of casting to void to suppress this warning:

// some "unused" variable you want to keep around
int some_var = 7;
// turn off `-Wunused` compiler warning for this one variable
// by casting it to void
(void)some_var;  // <===== SOLUTION! ======

For C++, this also works on functions which return a variable marked with [[nodiscard]]:

C++ attribute: nodiscard (since C++17)
If a function declared nodiscard or a function returning an enumeration or class declared nodiscard by value is called from a discarded-value expression other than a cast to void, the compiler is encouraged to issue a warning.
(Source: https://en.cppreference.com/w/cpp/language/attributes/nodiscard)

So, the solution is to cast the function call to void, as this is actually casting the value returned by the function (which is marked with the [[nodiscard]] attribute) to void.

Example:

// Some class or struct marked with the C++ `[[nodiscard]]` attribute
class [[nodiscard]] MyNodiscardClass 
{
public:
    // fill in class details here
private:
    // fill in class details here
};

// Some function which returns a variable previously marked with
// with the C++ `[[nodiscard]]` attribute
MyNodiscardClass MyFunc()
{
    MyNodiscardClass myNodiscardClass;
    return myNodiscardClass;
}

int main(int argc, char *argv[])
{
    // THE COMPILER WILL COMPLAIN ABOUT THIS FUNCTION CALL
    // IF YOU HAVE `-Wunused` turned on, since you are 
    // discarding a "nodiscard" return type by calling this
    // function and not using its returned value!
    MyFunc();

    // This is ok, however, as casing the returned value to
    // `void` suppresses this `-Wunused` warning!
    (void)MyFunc();  // <===== SOLUTION! ======
}

Lastly, you can also use the C++17 [[maybe_unused]] attribute: https://en.cppreference.com/w/cpp/language/attributes/maybe_unused.

Gabriel Staples
  • 36,492
  • 15
  • 194
  • 265
5

Instead of putting it on top of the file (or even a header file), just wrap the code in question with #pragma warning (push), #pragma warning (disable) and a matching #pragma warning (pop), as shown here.

Although there are some other options, including #pramga warning (once).

Christian.K
  • 47,778
  • 10
  • 99
  • 143
3

If you want to disable unreferenced local variable write in some header

template<class T>
void ignore (const T & ) {}

and use

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 
Alexey Malistov
  • 26,407
  • 13
  • 68
  • 88
  • 3
    A function call, just to suppress the warning? Why don't you do this instead : `(void)unusedVar;`? – Nawaz Aug 23 '11 at 10:25
  • @Nawaz: I think `(void)unusedVar;?`is not C++ Standard conformant. – Alexey Malistov Aug 23 '11 at 10:34
  • No reference is needed. C++ standard. It is not valid code. What is this? Expression? Function call? typedef? class declaration? – Alexey Malistov Aug 23 '11 at 11:41
  • 3
    Its an expression whose value is nothing. In C++, you can even do `static_cast(unusedVar)`. – Nawaz Aug 23 '11 at 12:00
  • 3
    @Nawaz. Herb Sutter explanation: http://herbsutter.com/2009/10/18/mailbag-shutting-up-compiler-warnings/ – Alexey Malistov Aug 23 '11 at 12:02
  • 3
    §5.2.9/4 says, `Any expression can be explicitly converted to type “cv void.” The expression value is discarded` according to which you can write `static_cast(unusedVar)` and `static_cast(unusedVar)` and `static_cast(unusedVar)`. All forms are valid. I hope it clarifies your doubt. – Nawaz Aug 23 '11 at 12:03
2

In certain situations you must have a named parameter but you don't use it directly.
For example, I ran into it on VS2010, when 'e' is used only inside a decltype statement, the compiler complains but you must have the named varible e.

All the above non-#pragma suggestions all boil down to just adding a single statement:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}
Adi Shavit
  • 16,743
  • 5
  • 67
  • 137