Смысл предупреждения "declaration hides class member"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.02.22 11:44
Оценка:
У MSVC++ с версий 19.xx появилось предупреждение 4458 (declaration of '...' hides class member). Предупреждение полезное, но выводится, в том числе, и для личных членов базовых классов, недоступных в текущем классе, чем сводит на нет всю инкапсуляцию:

class C1 {

  int i1;

};

class C2 : public C1 {

  int i2;

public:

  int Get (int i1) const { return i1 + i2; }

};


Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?

Кстати, давно уже есть подозрение, что ключом /W4, не говоря уже о /Wall, в MS пользуется очень ограниченная группа людей (и преимущественно на тестовых примерах), а подавляющее большинство ограничивается максимум /W3. Иначе невозможно объяснить подобные казусы, а также то, что во многих случаях оборачивание проблемного фрагмента в __pragma (warning (push)), __pragma (warning (disable: ...)) и __pragma (warning (pop)) не позволяет подавить предупреждения — только глобальным запретом.
warning 4458
Re: Смысл предупреждения "declaration hides class member"
От: T4r4sB Россия  
Дата: 12.02.22 12:01
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>У MSVC++ с версий 19.xx появилось предупреждение 4458 (declaration of '...' hides class member). Предупреждение полезное, но выводится, в том числе, и для личных членов базовых классов, недоступных в текущем классе, чем сводит на нет всю инкапсуляцию:


ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?


Хм, выглядит как баг, можно зарепортить. Предупреждать об идентификаторах, которые один хрен недоступны, смысла явно нету.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Смысл предупреждения "declaration hides class member"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.02.22 13:01
Оценка: 1 (1)
Здравствуйте, T4r4sB, Вы писали:

TB>выглядит как баг, можно зарепортить.


Оказывается, уже репортили в 2019-м — до сих пор under investigation. Что опять же довольно четко показывает, что большинство ребят из MS компиляют свое максимум на /W3, иначе на эти грабли наступали бы слишком часто, и давно бы поправили.

Дописал туда уточнение про недоступность членов.
Re: Смысл предупреждения "declaration hides class member"
От: Alexander G Украина  
Дата: 12.02.22 13:15
Оценка: 1 (1)
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?


В других вариантах есть. Хотя есть и мнение, что в целом бесполезный ворнинг.
Мне помогал, когда в лямбде захваченная переменная затенялась другой.
В этом случае, ну, махнуть рукой и назвать иначе.
Многими принято соглашение об именовании, где члены данные именуются не так, как параметры, и такой ситуации просто не возникает.

ЕМ>Кстати, давно уже есть подозрение, что ключом /W4, не говоря уже о /Wall, в MS пользуется очень ограниченная группа людей (и преимущественно на тестовых примерах), а подавляющее большинство ограничивается максимум /W3.


Не знаю, как в MS, а мы (не в MS) пользуемся /W4, и ещё некоторыми сверх того иногда. Про полный /Wall разделяю подозрение.
Русский военный корабль идёт ко дну!
Re[2]: Смысл предупреждения "declaration hides class member"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.02.22 13:45
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>есть и мнение, что в целом бесполезный ворнинг.


Это явная глупость. Типичный пример: в функции-члене есть единичное использование переменной-члена, затем проект попадает к другому разработчику (или автор просто забывает об этой маловажной и неочевидной переменной), и в функцию добавляется локальная переменная или параметр с таким же именем.

AG>Многими принято соглашение об именовании, где члены данные именуются не так, как параметры, и такой ситуации просто не возникает.


Такие соглашения (и многие другие) порождены главным образом убожеством компиляторов, не умевших давать нужные предупреждения.

AG>Не знаю, как в MS, а мы (не в MS) пользуемся /W4, и ещё некоторыми сверх того иногда. Про полный /Wall разделяю подозрение.


Я с самого начала использования C/C++ подсел на полный набор предупреждений, глобально отключая только откровенно бесполезные для конкретного проекта, вроде "unreferenced inline function will be removed". А как только узнал про /Wall, стал его ставить по умолчанию везде. Много раз спасало от вдумчивого ковыряния в коде при поиске неявных ошибок.
Re: Смысл предупреждения "declaration hides class member"
От: sergii.p  
Дата: 12.02.22 18:19
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?


а в чём вред? По-моему, полезное предупреждение. Переименуйте переменную и явно укажите читающему, какая переменная берётся. Компилятору это конечно очевидно. А зачем человеку в этих хитросплетениях разбираться? Как минимум возникает вопрос: "может тут ошибка, и стоит брать именно С1::i1?"
Re[2]: Смысл предупреждения "declaration hides class member"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 12.02.22 19:06
Оценка:
Здравствуйте, sergii.p, Вы писали:

SP>а в чём вред?


В привлечении внимания к тому, что в норме вообще не должно быть заметным.

SP>По-моему, полезное предупреждение.


Безусловно — но, как я сразу же подчеркнул, лишь в соответствующих условиях.

SP>Переименуйте переменную


Не хочу. Хочу, чтоб соблюдался принцип инкапсуляции.

SP>Как минимум возникает вопрос: "может тут ошибка, и стоит брать именно С1::i1?"


Если прочитать исходное сообщение внимательно — не возникает.
Re[3]: Смысл предупреждения "declaration hides class member"
От: SaZ  
Дата: 16.02.22 11:22
Оценка: -2
Здравствуйте, Евгений Музыченко, Вы писали:

SP>>Переименуйте переменную


ЕМ>Не хочу. Хочу, чтоб соблюдался принцип инкапсуляции.


Казалось бы, а причём тут именование переменных к инкапсуляции. Ворнинг правильный, обычно указывает на проблемы с кодстайлом. Возьмите подход из unreal engine, где у входных параметров пишется префикс "in".
Re[4]: Смысл предупреждения "declaration hides class member"
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 16.02.22 11:45
Оценка: +1
Здравствуйте, SaZ, Вы писали:

SaZ>Казалось бы, а причём тут именование переменных к инкапсуляции.


Именно — правильно реализованная инкапсуляция никак не должна ограничивать свободу именования переменных. Если член базового класса закрыт для потомков, то его имя (и вообще факт наличия) никак не должен конфликтовать с их кодом. Ошибки вроде "member 'xxx' is inaccessible" выдаются прежде всего с наводящей целью, чтобы разработчики не гадали, где теряется видимость.

SaZ>Ворнинг правильный, обычно указывает на проблемы с кодстайлом. Возьмите подход из unreal engine, где у входных параметров пишется префикс "in".


Типичный пример извращенного мышления — предлагать костыль там, где можно было бы обеспечить независимость.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.