Unused parameter in c++11
Unused parameter in c++11
In c++03 and earlier to disable compiler warning about unused parameter I usually use such code:
#define UNUSED(expr) do { (void)(expr); } while (0)
For example
int main(int argc, char *argv)
{
UNUSED(argc);
UNUSED(argv);
return 0;
}
But macros are not best practice for c++, so.
Does any better solution appear with c++11 standard? I mean can I get rid of macros?
Thanks for all!
No! Do not do that!
– Lightness Races in Orbit
Apr 2 '13 at 12:22
How much better is that macro than expanding it inline?
(void)argc;
is shorter and clearer than UNUSED(argc);
– David Rodríguez - dribeas
Apr 2 '13 at 12:45
(void)argc;
UNUSED(argc);
I like
unused(argc, argv)
with template<class... T> void unused(T&&...){}
. Clear, concise, and without macros.– Xeo
Apr 2 '13 at 12:56
unused(argc, argv)
template<class... T> void unused(T&&...){}
@MadScientist but you may leave unnamed argument, or even just comment out it's name.
void foo(int /*unused_arg*/, int used_arg)
– kassak
Apr 2 '13 at 15:53
void foo(int /*unused_arg*/, int used_arg)
12 Answers
12
I have used a function with an empty body for that purpose:
template <typename T>
void ignore(T &&)
{ }
void f(int a, int b)
{
ignore(a);
ignore(b);
return;
}
I expect any serious compiler to optimize the function call away and it silences warnings for me.
When
T
is a template parameter, T&&
is a universal reference which binds to anything.– Angew
Apr 2 '13 at 13:02
T
T&&
+1 Even though Xeo's advanced version from his comment isn't even mentioned.
– Christian Rau
Apr 2 '13 at 14:33
Why ignore the built-in method? Simply omit the parameter name.
– Jack Aidley
Apr 2 '13 at 17:21
-1, this is ridiculous and an unnecessary contraption, especially when you can just omit the param name. Frankly, it bothers me that this has 25 upvotes somehow.
– TC1
Apr 3 '13 at 21:19
@TC1 This is making your code explicit about what it does and why. Having unused parameters or variables is a smell in your code and this makes it explicit. Turning off the warning makes your code smell more.
– dascandy
Apr 16 '13 at 8:35
You can just omit the parameter names:
int main(int, char *)
{
return 0;
}
And in the case of main, you can even omit the parameters altogether:
int main()
{
// no return implies return 0;
}
See "§ 3.6 Start and Termination" in the C++11 Standard.
And in the case of
main
, you can omit the parameters altogether. And the return
statement, for that matter.– Mike Seymour
Apr 2 '13 at 12:20
main
return
@MikeSeymour I actually consider it good practice to omit the return statement.
– Jonas Tepe
Apr 2 '13 at 12:23
@jotep Okay, I'll bite. Why do you consider it good practice?
– Peter Wood
Apr 2 '13 at 12:52
I almost always omit
main
's return 0
in a testcase, but almost always write the self-documenting return EXIT_SUCCESS
in production code. That's good practice!– Lightness Races in Orbit
Apr 2 '13 at 13:10
main
return 0
return EXIT_SUCCESS
this seems like the best answer to me - anything that futzes with macros or templates still doesn't ensure that the variable can't be used afterwards. This both silences the warning and ensures that the (unnamed) parameter can't ever be used.
– Alnitak
Apr 2 '13 at 13:39
There is the <tuple>
in C++11, which includes the ready to use std::ignore
object, that's allow us to write (very likely without imposing runtime overheads):
<tuple>
std::ignore
void f(int x)
{
std::ignore = x;
}
Considering this is in the standard library and therefore doesn't involve having to write custom functions I'd say this is the best solution!
– BrainStone
Oct 10 '16 at 1:30
Nothing equivalent, no.
So you're stuck with the same old options. Are you happy to omit the names in the parameter list entirely?
int main(int, char**)
In the specific case of main
, of course, you could simply omit the parameters themselves:
main
int main()
There are also the typical implementation-specific tricks, such as GCC's __attribute__((unused))
.
__attribute__((unused))
To "disable" this warning, the best is to avoid writing the argument, just write the type.
void function( int, int )
{
}
or if you prefer, comment it out:
void function( int /*a*/, int /*b*/ )
{
}
You can mix named and unnamed arguments:
void function( int a, int /*b*/ )
{
}
With C++17 you have [[maybe_unused]] attribute specifier, like:
void function( [[maybe_unused]] int a, [[maybe_unused]] int b )
{
}
I used to do this, but it quickly becomes a pain since you can no longer comment out large chunks of code with
/* ... */
– Ponkadoodle
Dec 14 '14 at 7:07
/* ... */
It's true but with modern IDEs I guess if you select a block to comment automatically, it will add a bunch of "//" at the beginning of each line. That's what Eclipse CDT does. Personally, I only use the first example with no name. (you can put names in the declarations in a .h file for instance).
– Nikko
Dec 15 '14 at 8:30
@Wallacoloo When I want to comment out large chunk of code, I use #if 0 ... #endif, which are allowed to be nested and never conflict with existing /* ... */ comments.
– Dmitry Frank
Jun 24 '15 at 15:37
@DmitryFrank And most editors and IDEs support graying out
#if 0
blocks as a special case even if they don't support full preprocessor intellisense.– Thomas
Jan 17 at 11:17
#if 0
Macros may not be ideal, but they do a good job for this particular purpose. I'd say stick to using the macro.
+1: In this instance, they cause zero harm and solve a problem. I don't see any reason (beyond the ridiculous baseless mantra of "never use a macro") not to employ them here.
– Lightness Races in Orbit
Apr 2 '13 at 12:29
What is the benefit of a macro over omitting the parameter name altogether?
– Micha Wiedenmann
Apr 2 '13 at 12:36
@MichaWiedenmann: Some parameters may only be used when some preprocessing constants are set (typically, in Debug).
– Matthieu M.
Apr 2 '13 at 12:39
@MatthieuM.: I'd call the macro
MAYBE_UNUSED
, for that reason; I typically don't care if I've said "don't worry if I don't use this below" but go on to do so anyway.– Lightness Races in Orbit
Apr 2 '13 at 12:43
MAYBE_UNUSED
Ok, so the correct thing is probably to call it "HIDE_UNUSED_WARNING". But I still think that using a macro here is a perfectly valid idea. As long as the macro is named in such a way that it doesn't cause confusion and/or conflicts with other code.
– Mats Petersson
Apr 2 '13 at 12:53
What do you have against the old and standard way?
void f(int a, int b)
{
(void)a;
(void)b;
return;
}
I find that some compilers are happy with this, but some compilers are pickier than others. Cross Platform work needs to be tested in all targeted OS and compilers to be sure they are all happy with the solution.
– Jesse Chisholm
Mar 31 '17 at 19:32
There's nothing new available.
What works best for me is to comment out the parameter name in the implementation. That way, you get rid of the warning, but still retain some notion of what the parameter is (since the name is available).
Your macro (and every other cast-to-void approach) has the downside that you can actually use the parameter after using the macro. This can make code harder to maintain.
The Boost header <boost/core/ignore_unused.hpp>
(Boost >= 1.56) defines, for this purpose, the function template boost::ignore_unused()
.
<boost/core/ignore_unused.hpp>
boost::ignore_unused()
int fun(int foo, int bar)
{
boost::ignore_unused(bar);
#ifdef ENABLE_DEBUG_OUTPUT
if (foo < bar)
std::cerr << "warning! foo < bar";
#endif
return foo + 2;
}
PS C++17 seems to be getting a [[maybe_unused]]
attribute to provide a standard way of declaring an unused variable.
[[maybe_unused]]
[[maybe_unused]]
is explicit way, currently best.– Orient
Nov 8 '16 at 5:43
[[maybe_unused]]
windows.h defines UNREFERENCED_PARAMETER:
#define UNREFERENCED_PARAMETER(P) {(P) = (P);}
So you could do it like this:
#include <windows.h>
#include <stdio.h>
int main(int argc, char **argv) {
UNREFERENCED_PARAMETER(argc);
puts(argv[1]);
return 0;
}
Or outside of Windows:
#include <stdio.h>
#define UNREFERENCED_PARAMETER(P) {(P) = (P);}
int main(int argc, char **argv) {
UNREFERENCED_PARAMETER(argc);
puts(argv[1]);
return 0;
}
This is not a very good option, because
operator=
may have side effects.– Tamás Szelei
Feb 28 '16 at 11:57
operator=
I really like using macros for this, because it allows you better control when you have different debug builds (e.g. if you want to build with asserts enabled):
#if defined(ENABLE_ASSERTS)
#define MY_ASSERT(x) assert(x)
#else
#define MY_ASSERT(x)
#end
#define MY_UNUSED(x)
#if defined(ENABLE_ASSERTS)
#define MY_USED_FOR_ASSERTS(x) x
#else
#define MY_USED_FOR_ASSERTS(x) MY_UNUSED(x)
#end
and then use it like:
int myFunc(int myInt, float MY_USED_FOR_ASSERTS(myFloat), char MY_UNUSED(myChar))
{
MY_ASSERT(myChar < 12.0f);
return myInt;
}
I have my own implementation for time critical segments of code.
I've been researching a while a time critical code for slow down and have found this implementation consumes about 2% from the time critical code i have being optimized:
#define UTILITY_UNUSED(exp) (void)(exp)
#define UTILITY_UNUSED2(e0, e1) UTILITY_UNUSED(e0); UTILITY_UNUSED(e1)
#define ASSERT_EQ(v1, v2) { UTILITY_UNUSED2(v1, v2); } (void)0
The time critical code has used the ASSERT*
definitions for debug purposes, but in release it clearly has cutted out, but... Seems this one produces a bit faster code in Visual Studio 2015 Update 3
:
ASSERT*
Visual Studio 2015 Update 3
#define UTILITY_UNUSED(exp) (void)(false ? (false ? ((void)(exp)) : (void)0) : (void)0)
#define UTILITY_UNUSED2(e0, e1) (void)(false ? (false ? ((void)(e0), (void)(e1)) : (void)0) : (void)0)
The reason is in double false ?
expression. It somehow produces a bit faster code in release with maximal optimization.
false ?
I don't know why this is faster (seems a bug in compiler optimization), but it at least a better solution for that case of code.
Note:
Most important thing here is that a time critical code slow downs without above assertions or unused macroses in release. In another words the double false ?
expression surprisingly helps to optimize a code.
false ?
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
Sure. Turn off the warning.
– Pete Becker
Apr 2 '13 at 12:20