Unused parameter in c++11

55,595

Solution 1

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.

Solution 2

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.

Solution 3

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):

void f(int x)
{
    std::ignore = x;
}

Solution 4

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 )
{
}

Solution 5

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:

int main()

There are also the typical implementation-specific tricks, such as GCC's __attribute__((unused)).

Share:
55,595
inkooboo
Author by

inkooboo

C++ developer. http://github.com/inkooboo

Updated on January 28, 2020

Comments

  • inkooboo
    inkooboo almost 3 years

    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!

    • Pete Becker
      Pete Becker over 9 years
      Sure. Turn off the warning.
    • Lightness Races in Orbit
      Lightness Races in Orbit over 9 years
      No! Do not do that!
    • David Rodríguez - dribeas
      David Rodríguez - dribeas over 9 years
      How much better is that macro than expanding it inline? (void)argc; is shorter and clearer than UNUSED(argc);
    • Xeo
      Xeo over 9 years
      I like unused(argc, argv) with template<class... T> void unused(T&&...){}. Clear, concise, and without macros.
    • Lightness Races in Orbit
      Lightness Races in Orbit over 9 years
      oh noes macros must not use macros
    • marco-fiset
      marco-fiset over 9 years
      If a parameter is not used, why is it there in the first place?
    • MadScientist
      MadScientist over 9 years
      Sometimes you need to conform to a certain interface (e.g. when overriding a virtual function or in generic programming).
    • Lightness Races in Orbit
      Lightness Races in Orbit over 9 years
      s/sometimes/most of the time/
    • kassak
      kassak over 9 years
      @MadScientist but you may leave unnamed argument, or even just comment out it's name. void foo(int /*unused_arg*/, int used_arg)
    • FrankHB
      FrankHB over 6 years
      @kassak That can't be done for "maybe" unused arguments, e.g. with conditional inclusion where one branch need the arguments and another branch does not. To wrap them also in #ifdef is too verbose. There would be [[maybe_unused]] in C++17, but it comes too late.
    • FrankHB
      FrankHB over 6 years
      @Xeo That also is not quite ideal because "unused" may be indicating working not only on arguments but also expressions. I use such construct to explicitly express intended unsequenced evaluation on non-void expressions. OTOH, "unused" is used more generally, implemented as cast to void.
    • FrankHB
      FrankHB over 6 years
      @DavidRodríguez-dribeas This is quite close to what I am using but I recently find it can't work for parameter packs. That's why I search for the answer and comes here. Sadly I still fail to find an ideal portable solution.
    • Tomilov Anatoliy
      Tomilov Anatoliy over 5 years
      You should not give answer in you question. It is unfair wrt who answers your question.
  • Mike Seymour
    Mike Seymour over 9 years
    And in the case of main, you can omit the parameters altogether. And the return statement, for that matter.
  • jtepe
    jtepe over 9 years
    @MikeSeymour I actually consider it good practice to omit the return statement.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    +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.
  • Micha Wiedenmann
    Micha Wiedenmann over 9 years
    What is the benefit of a macro over omitting the parameter name altogether?
  • Matthieu M.
    Matthieu M. over 9 years
    @LightnessRacesinOrbit: As highlighted by Angew, one issue is that you can actually use the parameter before/after using the macros; silly right ? Well, in code that is heavy with preprocessing directives it's not immediate that you are currently in a branch that is using the parameter or not :(
  • Matthieu M.
    Matthieu M. over 9 years
    @MichaWiedenmann: Some parameters may only be used when some preprocessing constants are set (typically, in Debug).
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @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.
  • Matthieu M.
    Matthieu M. over 9 years
    @LightnessRacesinOrbit: fair enough :)
  • Peter Wood
    Peter Wood over 9 years
    @jotep Okay, I'll bite. Why do you consider it good practice?
  • Mats Petersson
    Mats Petersson over 9 years
    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.
  • Suma
    Suma over 9 years
    T && will not accept parameter (parameter is l-value), will it? Would ignore(T const &) be more suitable?
  • Angew is no longer proud of SO
    Angew is no longer proud of SO over 9 years
    When T is a template parameter, T&& is a universal reference which binds to anything.
  • jtepe
    jtepe over 9 years
    @MikeSeymour If it's the default return value that ends main, I omit it, since it's unnecessary boilerplate.
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    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
    Lightness Races in Orbit over 9 years
    @MadScientist: Hmm, interesting...!
  • Alnitak
    Alnitak over 9 years
    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.
  • Christian Rau
    Christian Rau over 9 years
    +1 Even though Xeo's advanced version from his comment isn't even mentioned.
  • Jack Aidley
    Jack Aidley over 9 years
    Why ignore the built-in method? Simply omit the parameter name.
  • frozenkoi
    frozenkoi over 9 years
    @MatthieuM. if the use of the parameters are only used inside some #ifdef blocks, you could put the name of the parameter inside such a conditional block too.
  • Matthieu M.
    Matthieu M. over 9 years
    @frozenkoi: Yes... but it's quite cumbersome because #ifdef and #endif directives need be placed on a line of their own, which really screw up the function header... to the point of it being nigh unreadable.
  • Sam
    Sam over 9 years
    You could use variadic template to write something like ignore(a, b, anythingElseThatBothersYou);
  • Lightness Races in Orbit
    Lightness Races in Orbit over 9 years
    @Alnitak: Yet at least two other answers say the same thing, plus other things, and actually address the question. This one does not.
  • TC1
    TC1 over 9 years
    -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.
  • Henrik
    Henrik over 9 years
    @LightnessRacesinOrbit About "saying the same thing": this is correct and I'm not sure why my answer receives the most upvotes. Maybe because it was the first one. About "actually addressing the problem": yes I could have explicitly stated, "There is no new C++11 feature", but the answer clearly implies there is no need for such a feature (or to use macros) to silence the warning.
  • Admin
    Admin over 9 years
    This works in cases where you never refer to the argument but are forced to receive it (e.g. in main, or a virtual function you are overriding). However, it's less useful if you only refer to the argument in a debug configuration for example. Conditionally omitting the parameter name is going to end up being pretty ugly! :)
  • dascandy
    dascandy over 9 years
    @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.
  • josefx over 9 years
    @dascandy there is no warning if you simply omit the name and having no name to reference the variable makes it explicit that you do not use it without having to add bloat.
  • jweyrich
    jweyrich over 9 years
    Try to use it in a constexpr function.
  • Xavi Montero
    Xavi Montero over 8 years
    unname them, so the function accepts the parameter, but does not assign it to any variable: int main( int /* argc */, char ** /* argv */ )
  • Ponkadoodle
    Ponkadoodle about 8 years
    I used to do this, but it quickly becomes a pain since you can no longer comment out large chunks of code with /* ... */
  • Nikko
    Nikko about 8 years
    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).
  • Dmitry Frank
    Dmitry Frank over 7 years
    @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.
  • Jean Davy
    Jean Davy over 7 years
    Don't reinvent the wheel ! Use boost, see that answer below
  • Janosimas
    Janosimas over 7 years
    I understand the question was for parameters but his answer can be used for RAII-style class like std::lock_guard. You don't "use" this kind of class and don't want a warning...
  • Timmmm
    Timmmm over 7 years
    This makes it much harder to read the code - you have to refer to the header where hopefully the parameter names have been left in order to understand which variables have been ignored. Better to comment them out.
  • Tamás Szelei
    Tamás Szelei almost 7 years
    This is not a very good option, because operator= may have side effects.
  • FrankHB
    FrankHB over 6 years
    The name is not good enough and might conflict to std::ignore if one has used using namespace std; naively.
  • The Marlboro Man over 6 years
    Necro comment, but instead of ommiting them you can always comment them out. It takes four more characters and all the information you will ever need is still on the source, without pesky warnings.
  • BrainStone
    BrainStone about 6 years
    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!
  • Tomilov Anatoliy
    Tomilov Anatoliy about 6 years
    [[maybe_unused]] is explicit way, currently best.
  • Jesse Chisholm
    Jesse Chisholm over 5 years
    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.
  • ManuelAtWork
    ManuelAtWork over 5 years
    Maybe one should declare the ignore function inline. (If the function is put into a header file and the compiler does not optimize, then there might be multiple instances of the same specialization in the object files.)
  • Thomas
    Thomas almost 5 years
    @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.
  • Maestro over 4 years
    This class is "Intended for use with std::tie when unpacking a std::tuple", not for this use case. I would say it's a solution, but probably not the best.
  • Maestro over 4 years
    boost/core/ignore_unused implements it the same way, so I think it's a good solution. If boost found that this method was useful enoug to include it in its library, I would say there must be good reason not to just comment out the parameter names...
  • Melroy van den Berg
    Melroy van den Berg over 3 years
    I like this ignore actually.. Ofc, if you can remove the parameter, remove this instead (that would be the best solution in all cases).
  • orion elenzil
    orion elenzil about 1 year
    this is great. and if you have to provide a default value, omit the name but you need to keep the value. eg, void foo(int a = 0, int unused = 0) -> void foo(int a = 0, int /* unused */ = 0)