[[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 intests/trace/views/groupmap_oracle.handtests/utilities/plugins/test_plugin_planner.cppwith Apple clang and-std=c++20. After the rewrite,cmake --build --preset testsgave 0 warnings.