51

Functional languages with pattern matching (sometimes?) have the possibility to ignore some bound values, but with C++17 structured bindings there seem to be no way to do that (std::ignore with structured bindings?). The advice is to use a dummy name, but then we'll get warnings about unused variables.

With the latest heads of both clang and gcc, this does the expected thing, which is nice and useful,

[[maybe_unused]] auto x =4 ; // fine, no warning
[[maybe_unused]] auto [a,dummyb,dummyc] = std::tuple<int,int,float>(1,1,1.0f); 

but I would also have hoped this would work:

auto [g,[[maybe_unused]]dummyh,[[maybe_unused]]dymmyi] =
      std::tuple<int,int,float>(1,1,1.0f);

is there a specific reason attributes can not be used here? (in the standard as well as technically). Neither gcc or clang accepts this.


Edit, collecting the support status: (thanks to godbolt/compiler explorer). It works as expected in (could be earlier also):

  • gcc 8.0 trunk (g++ 8.0.0 20171015 experimental)
  • clang 4.0.0
  • icc 18 (not tested, according to specs)
  • msvc 19.22 (probably earlier) (Fixed, according to bug report)

Try it out in godbolt at https://gcc.godbolt.org/z/H2duYd

Johan Lundberg
  • 26,184
  • 12
  • 71
  • 97
  • 2
    I imagine that potentially blocking nested decompositions might have been a concern. – T.C. Dec 30 '16 at 23:57
  • 1
    Hmm. Ok... `[g,[[possibly_unused]]] = foo()`.. The more I think about it, the more I'm just fine with putting that single attribute on the outside :-) – Johan Lundberg Dec 31 '16 at 00:08
  • 1
    Indeed requires gcc > 7.2 to make the attribute work. – Trass3r Sep 13 '17 at 12:11
  • 1
    So [[maybe_unused]] prevents the warning but then you also lose any checks for the return values you actually want to use. – Trass3r Sep 13 '17 at 12:15

2 Answers2

30

In the structure bindings paper:

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2016/p0144r2.pdf

they discuss their reasoning:

3.8 Should there be a way to explicitly ignore components?

The motivation would be to silence compiler warnings about unused names.

We think the answer should be “not yet.” This is not motivated by use cases (silencing compiler warnings is a motivation, but it is not a use case per se), and is best left until we can revisit this in the context of a more general pattern matching proposal where this should fall out as a special case.

Symmetry with std::tie would suggest using something like a std::ignore:

   tuple<T1,T2,T3> f(); 
   auto [x, std::ignore, z] = f(); // NOT proposed: ignore second element 

However, this feels awkward.

Anticipating pattern matching in the language could suggest a wildcard like _ or *, but since we do not yet have pattern matching it is premature to pick a syntax that we know will be compatible. This is a pure extension that can wait to be considered with pattern matching.

Although this does not explicitly address [[maybe_unused]], I assume the reasoning might be the same. Stopping compiler warnings is not a use-case.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
Mikel F
  • 3,567
  • 1
  • 21
  • 33
  • 9
    If `maybe_unused` has a use case, then attaching `maybe_unused` to a variable that's declared in a structured binding has a use case. It's just another way of declaring a variable. – mackenir Feb 04 '20 at 17:38
  • This still lacks reasoning on why attrubute syntax is not allowed. For example: `for (auto& [x, y [[gnu::whatever]], z] = f() ) { .. }` . It doesn't matter what `gnu::whatever` might mean - the attribute syntax is open for future extensions. Not very useful would be the reasoning that the current available set of attributes in C++20 are unlikely to be used in this context. – Ethouris Nov 10 '21 at 16:56
  • @Ethouris At the time this question was asked, C++17 was still unpublished, so whether or not it was addressed in C++20 was not really a known thing when this answer was provided. – Mikel F Nov 10 '21 at 18:30
  • 1
    But even in C++20 the problem still doesn't seem to be solved, and I don't think the reasoning has changed. I'm using currently `for ([[maybe_unused]] auto& [x, y, z] = f() )`, which solves the problem of the warning, but hides the others. And the case when this is used isn't that rare - for example if you loop around the map, but you are not interested in the values of the keys. – Ethouris Nov 11 '21 at 08:40
13

As a resolution to CWG 2360, the working draft of the standard gained the following wording ([dcl.attr.unused]):

  1. The attribute may be applied to the declaration of a class, a typedef-name, a variable (including a structured binding declaration), a non-static data member, a function, an enumeration, or an enumerator.

  2. For an entity marked maybe_unused, implementations should not emit a warning that the entity or its structured bindings (if any) are used or unused. For a structured binding declaration not marked maybe_unused, implementations should not emit such a warning unless all of its structured bindings are unused.

Structured binding declarations were previously not explicitly mentioned.

Community
  • 1
  • 1
metalfox
  • 6,301
  • 1
  • 21
  • 43