-Wshadow=global 将枚举 class 条目视为全局阴影。为什么?

-Wshadow=global considers enum class entry shadowing a global. Why?

在 GCC 7.3 和 8.2 上使用 -Wshadow=global 进行编译时,编译器会警告以下代码片段存在阴影。

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;
               ^

因为 enum classes 在引用时需要 enum class 名称,我的理解是 A 的所有三个声明都是分开的:::A::Bar::A, 和 ::Foo::A.

Clang 7 不会发出带有 -Wshadow 的警告。

这是有效的阴影警告吗?如果是,为什么?

我想你可以考虑一个愚蠢的场景,

enum class Foo {
    A = 0,    // warns this entry shadows global declaration of A
    B = A
};

所以B定义中对A的引用可以来自全局A和局部A.

关于此问题的错误已提交,标题为 "-Wshadow generates an incorrect warning with enum classes"。但是,无法确认这是一个错误。

Jonathan Wakely 认为这不是错误并给出了以下示例。

typedef unsigned char foo;
enum class myenum
{
  foo,
  bar = (foo)-1
};

Is the value -1L or 255?

If I rename myenum::foo to myenum::Foo the code silently changes meaning.

It also changes meaning if I reorder the declarations of myenum::foo and myenum::bar, which is exactly the sort of fragile code that deserves a warning.

问题中发布的示例也是如此。如果在 enum class Foo 之后 声明全局 int A,则不再有警告。

另一个用户同意该主题:

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.