When compiling with -Wshadow=global on GCC 7.3 and 8.2, the compiler warns that the following code snippet shadows.
constexpr int A = 0;
class Bar {
public:
enum Bars {
A = 0
};
};
enum class Foo {
A = 0 // warns this entry shadows global declaration of A
};
int main() {
return 0;
}
<source>:11:9: warning: declaration of 'A' shadows a global declaration [-Wshadow]
A = 0
^
<source>:1:15: note: shadowed declaration is here
constexpr int A = 0;
^
Because enum classes require the enum class name when referenced, my understanding is that all three declarations of A
are separate: ::A
, ::Bar::A
, and ::Foo::A
.
Clang 7 doesn't emit a warning with -Wshadow.
Is this a valid shadow warning, and if so, why?
There has been a bug that has been already filed about this issue titled "-Wshadow
generates an incorrect warning with enum classes" . However, it is not confirmed that this is a bug.
Jonathan Wakely argues that this is not a bug and gives the following example.
typedef unsigned char foo; enum class myenum { foo, bar = (foo)-1 }; Is the value -1L or 255?
If I rename
myenum::foo
tomyenum::Foo
the code silently changes meaning.It also changes meaning if I reorder the declarations of
myenum::foo
andmyenum::bar
, which is exactly the sort of fragile code that deserves a warning.
This is true for the example posted in the question as well. If the global int A
is declared after the enum class Foo
, there is no longer a warning.
Another user agrees on that thread:
In an ideal world we would only warn when ambiguity exists (in the user mind), that is, at "bar = (foo) -1". However, that is probably much more difficult and expensive than the current warning.
I guess you can consider a silly scenario,
enum class Foo {
A = 0, // warns this entry shadows global declaration of A
B = A
};
So the reference to A
in the definition of B
can be from global A
and local A
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With