结构化绑定和基于范围的;在 gcc 中抑制未使用的警告

structured bindings and range-based-for; supress unused warning in gcc

我想使用结构绑定遍历映射,忽略键:

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

我已经尝试了 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]].

[[maybe_unused]] 属性似乎还没有为结构绑定实现。

有什么简单的解决方法吗?任何宏、gcc/gnu 扩展名或任何暂时禁止该特定警告的编译指示对我来说都可以;例如,在我使用 range-based-for 的整个函数体中禁用它,因为我使用的函数非常短(它基本上是两个具有精确行为的不同映射上的两个 range-for-loops ).

我用来编译项目的(相关)选项是:

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

我目前要继续的是,但这很难看:

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

记录了相关的 GCC pragmas 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);

}

这是我可以拥有的最小范围的禁用警告,并且仍然使用 -Wall -Wextra -Werror 抑制了警告。

看来你是对的,gcc 7.2.0 中的结构化绑定还没有实现 maybe_unused 属性,但值得注意的是,它似乎是为 gcc 8.0 trunk (g++ 8.0. 0 20171026 实验)。

使用gcc 8.0 trunk编译,下面会发出-Wunused-variable警告:

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

而这不会:

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

特别是,删除 [[maybe_unused]] 但至少使用一个有界变量也不会产生警告(故意的?)。

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

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