ON_BLOCK_EXIT is a utility macro provided by the ScopeGuard implementation. It defines a local object for the sole reason of having its user-provided destructor executed when it falls out of scope. It is defined as:
#define CONCATENATE_DIRECT(s1, s2) s1##s2
#define CONCATENATE(s1, s2) CONCATENATE_DIRECT(s1, s2)
#define ANONYMOUS_VARIABLE(str) CONCATENATE(str, __LINE__)
#define ON_BLOCK_EXIT ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = MakeGuard
and can be used like this:
void foo() {
HANDLE hFile = CreateFile( ... );
ON_BLOCK_EXIT( CloseHandle, hFile );
// more...
// ... code...
// ... following
} // warning C4189
When compiled with Visual Studio 2010 the code above generates the following warning C4189: 'scopeGuard3' : local variable is initialized but not referenced.
#pragma warning( suppress : 4189 ) could be used to temporarily disable the warning. This, however, has 2 issues: 1.) It cannot be placed next to the statement that causes the warning but has to go right above the line that ends the scope. 2.) As a corollary to this it will mask out all warnings 4189 resulting from the current scope.
Using Visual Studio 2010 is there any way to disable this specific warning resulting from just those objects created with ON_BLOCK_EXIT (preferably without having to alter the call site, similar to GCC's __attribute__((unused)))?
The solution I finally went for works for Visual Studio 2005 or later:
#define ON_BLOCK_EXIT( ... ) ScopeGuard ANONYMOUS_VARIABLE(scopeGuard) = \
MakeGuard( __VA_ARGS__ ); \
(void)ANONYMOUS_VARIABLE(scopeGuard)
The original macro did not expand to a complete expression so there was no way to append any instrumentation to instruct the compiler to not raise a warning. Using variadic macros provided that option.
Related
I am using an API which return int error codes and I decided to build a wrapper error class :
class Error
{
...
public:
Error(int ErrC, const char* UserMessage, const char* FileName, int LineNumber, const char* Function);
char * GetFunction();
...
}
I decided to venture into the world of macros and create a macro to instantiate the class for me :
#define API_ERROR(Code,MSG) API::Error(Code,MSG,__FILE__,__LINE__,__FUNCSIG__)
I then defined a Test function that is called by main
void TestFunc()
{
API::Error Error = API_ERROR(0,"Hello");
std::cout << Error.GetFunction();
}
Using the compiler option to output the post pre-processing results (Properties->C/C++->Preprocessor->Preprocess to a file) yielded
void TestFunc()
{
API::Error Error = API::Error(o,"Hello","...\\main.cpp",30,);
std::cout << Error.GetFunction();
}
I think this does not work because __FUNCSIG__ is only defined inside functions.
I have also tried
#define EMPTY()
#define DEFER(...) __VA_ARGS__ EMPTY()
#define API_ERROR(Code,MSG) API::Error(Code,MSG,__FILE__,__LINE__,DEFER(__FUNCSIG__))
But I think I misunderstood the author of the post.
Is there a way to make this work ?
I am using Visual Studio 2019 Community with the default MSVC++ compiler.
From this VS2019 predefined macro reference
The __FUNCSIG__ macro isn't expanded if you use the /EP or /P compiler option.
[Emphasis mine]
If you preprocess your source then the /EP or /P flags would be set, and the macro won't be expanded. It will only be expanded when actually building your source.
The __FUNCSIG__ macro will probably not be expanded by the preprocessor because it doesn't really know anything about C++ symbols. It might not even be a true preprocessor macro, and could be "expanded" (or replaced) at a later stage in compilation when C++ symbols are known.
In Visual C++ you can temporarily disable a warning by using pragma:
#pragma warning(suppress: 4307)
How can I disable a warning within a macro, e.g., when I cause an "integral constant overflow" warning like this:
#define TIMES_A_MILLION(x) x * 1000000
int value = TIMES_A_MILLION(4711);
I don't want to repeat the warning at every place where the macro is used, but want the suppression to be part of the macro it self.
It is obviously not possible to do like this:
#define TIMES_A_MILLION(x) \
#pragma warning(suppress: 4307) \
x * 1000000
In your case you have to use the extension __pragma
__pragma
instead of
#pragma
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.
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop )
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.
#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
{
// ...
}
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
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 )
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
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)
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).
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.
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
// ...
}
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
}
I can do this in Visual C++ 2008 with Release (NDEBUG) setting:
debug.h
#ifdef _DEBUG
void debug_printf(const char* format, ...);
#else
#define debug_printf(format, v) __noop
#endif
debug.cpp
#include "stdafx.h" //#include "debug.h" is inside it
void debug_printf(const char* format, ...) {
//so much work here
}
but not anymore in Visual C++ 2013, I will get compile error in debug.cpp file. It seems I have to change the defining strategy in debug.h. But I wonder is there compiler setting to reenable again the old way?
Use a macro in the first case too, and let it call the actual function (which is named something different from the macro).
And in the second case, just have an empty macro body.
Use variadic macros.
Something like
#ifdef _DEBUG
# define debug_printf(fmt, ...) real_debug_printf(fmt, __VA_ARGS__)
#else
# define debug_printf(fmt, ...)
#endif
When _DEBUG is not defined, then the macro debug_printf is replaced by nothing (or rather, an empty line).
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.
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop )
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.
#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
{
// ...
}
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
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 )
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
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)
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).
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.
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
// ...
}
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
}