Search code examples
c++gcclanguage-lawyerc++17structured-bindings

Why does GCC diagnose a unused variable for structured bindings while Clang doesn't?


Let's start with a minimal example:

#include <utility>

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

Compiling with GCC 7.3 passing -std=c++17 and -Wunused-variable, and running it:

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

GCC may be correctly reporting the absent use of b, but it wrongly calls it a variable. Quoting [dcl.struct.bind]/1:

A structured binding declaration introduces the identifiers v0, v1, v2, … of the identifier-list as names ([basic.scope.declarative]) of structured bindings.

So b clearly isn't a variable, but rather a name. Compiling the same code with Clang 6.0.0, and with the same flags, we get no warning whatsoever. Removing the return a; statement from the code:

#include <utility>

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

and compiling it again with Clang, we get:

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

Which, from my interpretation, correctly treats [a, b] as a variable, and a and b separately as just names. My question then is why does GCC diagnose a warning for b being unused, considering that the variable is in fact being used in the return a; statement from the first code?


Solution

  • This was indeed a bug in gcc: https://gcc.gnu.org/bugzilla/show_bug.cgi?format=multiple&id=81767 and was solved in: https://gcc.gnu.org/viewcvs/gcc?view=revision&revision=248483