-Wshadow = global считает, что запись в enum-классе затеняет глобальную.Зачем? - PullRequest
0 голосов
/ 19 декабря 2018

При компиляции с -Wshadow = global в GCC 7.3 и 8.2 компилятор предупреждает, что в следующем фрагменте кода тени.

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 требуется указание имени класса enum при ссылке, я понимаю, что все три объявления A являются отдельными: ::A, ::Bar::A и ::Foo::A.

Clang 7 не выдает предупреждение с -Wshadow.

Это правильное теневое предупреждение, и если да, то почему?

Ответы [ 2 ]

0 голосов
/ 19 декабря 2018

Об этой проблеме уже сообщалось об ошибке под названием "-Wshadow выдает неправильное предупреждение с перечислением классов" .Тем не менее, это не подтверждает, что это ошибка.

Джонатан Уэйкли утверждает, что это не ошибка, и приводит следующий пример.

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".Однако это, вероятно, намного сложнее и дороже, чем нынешнее предупреждение.

0 голосов
/ 19 декабря 2018

Полагаю, вы можете рассмотреть глупый сценарий,

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

Так что ссылка на A в определении B может быть глобальной A и локальной A.

...