【问题标题】:Why does GCC diagnose a unused variable for structured bindings while Clang doesn't?为什么 GCC 会诊断结构化绑定的未使用变量,而 Clang 不会?
【发布时间】:2018-04-15 18:35:42
【问题描述】:

让我们从一个最小的例子开始:

#include <utility>

int main()
{
    auto [a, b] = std::pair(1, 'A');
    return a;
}

使用 GCC 7.3 编译并传递 -std=c++17-Wunused-variable,并运行它:

<source>: In function 'int main()':
<source>:5:15: warning: unused variable 'b' [-Wunused-variable]
     auto [a, b] = std::pair(1, 'A');
               ^

GCC 可能正确地报告了b 的不使用,但它错误地将其称为变量。引用[dcl.struct.bind]/1:

结构化绑定声明将 identifier-listidentifiers v0、v1、v2……作为结构化绑定的名称 ([basic.scope.declarative]) .

所以b 显然不是一个变量,而是一个名称。使用 Clang 6.0.0 和相同的标志编译相同的代码,我们不会收到任何警告。从代码中删除return a; 语句:

#include <utility>

int main()
{
    auto [a, b] = std::pair(1, 'A');
    // return a;
}

然后用 Clang 再次编译,我们得到:

<source>:5:10: warning: unused variable '[a, b]' [-Wunused-variable]
    auto [a, b] = std::pair(1, 'A');
         ^

根据我的解释,它正确地将[a, b] 视为变量,而将ab 分别视为名称。 我的问题然后是考虑到变量实际上是在第一个代码的return a; 语句中使用的,为什么 GCC 会诊断出 b 未使用的警告?

【问题讨论】:

  • 什么返回声明?仅返回 a,而不返回 b。附言因为这是一个常见的习惯用法,有结构化的绑定,据报道这个警告信息不再由 gcc 8 发出。
  • 如果它们不是变量,你怎么能取到它们的地址呢?例如auto p = &amp;a;
  • @NeilButterworth 它们是结构底层成员的名称。实际变量没有得到标识符。
  • 它们是名称与它们是变量并不冲突。或者简单地说,它们还能是什么?
  • “为什么 GCC 会诊断结构化绑定的未使用变量,而 Clang 不会?” - 因为编译器是不同的,诊断不同的东西(并且有不同的错误),并且有不同级别的标准一致性。

标签: c++ gcc language-lawyer c++17 structured-bindings


【解决方案1】:
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-26
  • 1970-01-01
相关资源
最近更新 更多