Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unnamed loop variable in range-based for loop?

Is there any way to not "use" the loop variable in a range-based for loop, but also avoid compiler warnings about it being unused?

For context, I'm trying to do something like the following. I have "treat warnings as errors" enabled, and I'd rather not do a hack like forcing the variable to be "used" by pointlessly mentioning it somewhere.

size_t getSize(const std::forward_list &list)
{
  size_t count = 0;
  for (auto & : list) // compile error, but if i do "auto &i" here, MSVC
                      // complains (reasonably) that i is unused
  {
    ++count;
  }
  return count;
}

I know there are other ways to do this, but let's say for argument's sake that I need to use a range-based for loop.

like image 516
Karu Avatar asked Feb 15 '14 01:02

Karu


2 Answers

You can define a macro:

#if defined(__GNUC__)
#  define UNUSED __attribute__ ((unused))
#elif defined(_MSC_VER)
#  define UNUSED __pragma(warning(suppress:4100))
#else
#  define UNUSED
#endif

...
for (auto &dummy UNUSED : list)
{
  ++count;
}
...

It works well with GCC and CLANG (not so sure about MSVC... I seem to remember that MSVC will disable the warning for the rest of the file).

Also:

template<class T> void unused(const T &) {}
...
for (auto &dummy : list)
{
  unused(dummy);

  ++count;
}
...

works on all compilers and shouldn't have any overhead (Mailbag: Shutting up compiler warnings).

The Boost header <boost/core/ignore_unused.hpp> (Boost >= 1.56) defines, for the same purpose, the function template boost::ignore_unused().

With C++11 also std::ignore is a good choice:

{
  std::ignore = dummy;
  // ...
}

Similar questions:

  • C++11 range-based for loop: how to ignore value?
  • C++11 range-based for loops without loop variable

PS C++17 seems to be getting a [[maybe_unused]] attribute to provide a standard way of declaring an unused variable.

like image 199
manlio Avatar answered Sep 18 '22 19:09

manlio


You can always state explicitly that the variable is guaranteed unused in the loop body:

ptrdiff_t size( std::forward_list const& list )
{
    ptrdiff_t count = 0;
    for( auto& dummy : list ) 
    {
        (void) dummy; struct dummy;    // Wrap this in a macro if you want.
        // Here everybody including compiler knows that dummy isn't used and can't be used.

        ++count;
    }
    return count;
}

The above is however much less clear than simply using an ordinary for-loop.

Not to mention simply calling size.

like image 26
Cheers and hth. - Alf Avatar answered Sep 18 '22 19:09

Cheers and hth. - Alf