At work we have a long-running project which is compiled successfully with GCC (8.2). When we tried to use clang-based tools (clang-tidy, the static analyzer, etc.), we discovered that clang sometimes reports an error on code accepted by GCC. Here's a recent example:
#include <vector>
struct Fox{};
using Foxes = std::vector<Fox>;
Foxes& foxes()
{
static Foxes f;
return f;
}
void foxy(Foxes& foxes = foxes())
{
(void)foxes;
}
The above is accepted by GCC (both 8.2 and 12.1) with -Wall -Wpedantic -Wextra -Wshadow -Werror
.
However, clang complains that error: default argument references parameter 'foxes'
.
https://godbolt.org/z/seEb1ahKP
It looks like clang considers the foxes
to the right of the =
sign the same as the foxes
to the left of it. GCC appears to consider the foxes
to the right of the =
to be the function defined earlier.
When GCC and clang disagree, at least one of them is usually wrong (unless the code is ill-formed but no diagnostic required). Which one is right here?
GCC's behavior seems suspect to me; I would have thought that at least a -Wshadow
warning should have been emitted for the parameter (a local variable) with the same name as a function defined at global scope.