-Wshadow = global认为枚举类条目是全局的。为什么?

时间:2018-12-18 21:51:46

标签: c++ gcc gcc-warning

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

由于枚举类在被引用时需要枚举类名称,因此我的理解是A的所有三个声明都是分开的:::A::Bar::A::Foo::A。 / p>

Clang 7不会通过-Wshadow发出警告。

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

2 个答案:

答案 0 :(得分:2)

关于此问题,已提交了一个名为"-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?
     

如果我将myenum::foo重命名为myenum::Foo,则代码会默默地改变含义。

     

如果我重新排列myenum::foomyenum::bar的声明,它的含义也发生了变化,这恰恰是一种脆弱的代码,值得警告。

对于问题中张贴的示例也是如此。如果全局int Aenum class Foo之后声明为 ,则不再发出警告。

另一个用户同意该线程:

  

在理想情况下,我们仅在存在歧义(在用户脑海中)(即“ bar =(foo)-1”)时发出警告。但是,这可能比当前警告更加困难和昂贵。

答案 1 :(得分:1)

我想您可以考虑一个愚蠢的情况

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

因此,A的定义中对B的引用可以来自全局A和局部A