为什么GCC会诊断结构化绑定的未使用变量而Clang不会?

7

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

#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的话:

结构化绑定声明将标识符列表中的标识符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 未使用的警告?


1
在这种情况下,b是一个变量。但通常情况下,b可能是任何东西,包括lambda或指向函数的指针。 - Clearer
2
@NeilButterworth它们是结构体底层成员的名称。实际变量不会获得标识符。 - Mário Feroldi
3
它们作为变量名并不与它们作为变量产生冲突。换句话说,它们还能是什么? - Passer By
1
@PasserBy,你会更惊讶地知道它确实是为了解决不同的术语而设计的 - Mário Feroldi
2
为什么GCC会诊断结构化绑定的未使用变量,而Clang则不会?因为编译器不同,会诊断不同的问题(并且有不同的错误),同时也具有不同的标准符合级别。 - Jesper Juhl
显示剩余5条评论
网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接