在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发出警告。
这是否是有效的阴影警告?如果是,为什么?
答案 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::foo
和myenum::bar
的声明,它的含义也发生了变化,这恰恰是一种脆弱的代码,值得警告。
对于问题中张贴的示例也是如此。如果全局int A
在enum 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
。