14

I want to traverse a map using structure bindings, ignoring the key:

for (auto& [unused, val] : my_map)
     do_something(val);

I have tried different options with gcc-7.2.0:

// The warning is issued
for ([[maybe_unused]] auto& [unused, val] : my_map)
      do_something(val);

// Syntax error
for (auto& [[[maybe_unused]] unused, val] : my_map)
      do_something(val);

// The same two combinations above with [[gnu::unused]].

It seems that the [[maybe_unused]] attribute is not implemented yet for structure bindings.

Is there any simple solution to this? Any macro, gcc/gnu extension, or any pragma to temporarily supress that specific warning is fine to me; for example, disabling it during the whole function body where I'm using the range-based-for, because the function I'm using this is pretty short (it is basically two range-for-loops over two different maps with exact behaviour).

The (relevant) options I'm using to compile the project are:

-std=c++17 -Wall -Wextra -Werror -pedantic -pedantic-errors

What I have current to go on is, but that's ugly:

for (auto& [unused, val] : my_map)
   (void)unused, do_something(val);
ABu
  • 10,423
  • 6
  • 52
  • 103
  • Related: [std::ignore with structured bindings](https://stackoverflow.com/questions/40673080/stdignore-with-structured-bindings). – dfrib Oct 29 '17 at 20:55
  • @dfri But I cannot use `std::ignore` because it is already a declared variable, and what I have is a declaration, so, I'm introducing new names. – ABu Oct 29 '17 at 20:57
  • 1
    Yes I've only posted a related link, not a dupe mark (as explained in the link, there are currently no equivalent for `std::ignore` for structured bindings, although the standard may introduce one at a later point). A comment to one of the answers in the linked thread also recommends using `maybe_unused` for warning suppression (covering all declarations in the binding), but I don't know if this is supported (as you've tested some variations) in the context of structured bindings in a range based loop. – dfrib Oct 29 '17 at 21:01

2 Answers2

11

It seems that you are right that the maybe_unused attribute is not implemented yet for structured bindings in gcc 7.2.0, but it's worth noting that it seems to be implemented for gcc 8.0 trunk (g++ 8.0.0 20171026 experimental).

Compiling using gcc 8.0 trunk, the following will emit a -Wunused-variable warning:

// warning: unused structured binding declaration [-Wunused-variable]
for (auto& [unused, val] : my_map) { }

Whereas this will not:

// no warning
for ([[maybe_unused]] auto& [unused, val] : my_map) { }

Peculiarly, removing [[maybe_unused]] but making use of at least one of the bounded variables will also not yield a warning (intended?).

// no warning
for (auto& [unused, val] : my_map)
{
    do_something(val);
}

// no warning
for (auto& [unused, val] : my_map)
{
    (void)unused;
}
dfrib
  • 70,367
  • 12
  • 127
  • 192
  • 2
    Thanks. Curious to know that in gcc-8 `[[maybe_unused]]` is not required at all (using only one of them is a very likely need; I think that is intended). – ABu Oct 29 '17 at 22:40
4

The relevant GCC pragmas are documented on this page.

#include <map>

std::map<int, int> my_map;

void do_something(int);

void loop()
{
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-variable"
    for (auto & [unused, val]: my_map)
#pragma GCC diagnostic pop
        do_something(val);

}

This is the smallest scope of the disabled warning that I could have, and still have the warning suppressed with -Wall -Wextra -Werror.

Sam Varshavchik
  • 114,536
  • 5
  • 94
  • 148