Ray's Knowledge Base

[[maybe_unused]] on one structured binding name is a C++26 extension

PitfallVerified 27 Sep 2026Holds anywhere
Pitfall. The symptom, what causes it, and the fix that was run and seen to work.

Symptom#

To silence an unused key in a C++20 loop such as for (auto& [k, v] : map), the attribute is put on the one name, and clang warns:

warning: an attribute specifier sequence attached to a structured binding declaration is a C++2c extension [-Wc++26-extensions]

The code was for (auto& [k [[maybe_unused]], accum] : map) and auto [ignored [[maybe_unused]], agg] = co_await ...;.

Cause#

An attribute on one structured binding name is a C++26 feature, as the warning says. In C++17 and C++20 an attribute can apply only to the whole declaration.

Fix#

Pick one:

  • Iterate the element and read the member you need: for (auto& entry : map) { auto& accum = entry.second; ... }.
  • Take one element of a returned pair or tuple directly: all = std::get<1>(co_await collect_all(...));.
  • Put the attribute on the whole declaration: [[maybe_unused]] auto [it, fresh] = m.try_emplace(k);. This compiled with no warning under -std=c++20.

Do not go back to (void)k; when the goal is to remove such casts.

Evidence#

  • dftracer-utils stage 11 (void-casts, 2026-09-27): four such warnings in tests/trace/views/groupmap_oracle.h and tests/utilities/plugins/test_plugin_planner.cpp with Apple clang and -std=c++20. After the rewrite, cmake --build --preset tests gave 0 warnings.