У 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)) не позволяет подавить предупреждения — только глобальным запретом.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>У MSVC++ с версий 19.xx появилось предупреждение 4458 (declaration of '...' hides class member). Предупреждение полезное, но выводится, в том числе, и для личных членов базовых классов, недоступных в текущем классе, чем сводит на нет всю инкапсуляцию:
ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?
Хм, выглядит как баг, можно зарепортить. Предупреждать об идентификаторах, которые один хрен недоступны, смысла явно нету.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[2]: Смысл предупреждения "declaration hides class member"
Здравствуйте, T4r4sB, Вы писали:
TB>выглядит как баг, можно зарепортить.
Оказывается, уже репортили в 2019-м — до сих пор under investigation. Что опять же довольно четко показывает, что большинство ребят из MS компиляют свое максимум на /W3, иначе на эти грабли наступали бы слишком часто, и давно бы поправили.
Дописал туда уточнение про недоступность членов.
Re: Смысл предупреждения "declaration hides class member"
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?
В других вариантах есть. Хотя есть и мнение, что в целом бесполезный ворнинг.
Мне помогал, когда в лямбде захваченная переменная затенялась другой.
В этом случае, ну, махнуть рукой и назвать иначе.
Многими принято соглашение об именовании, где члены данные именуются не так, как параметры, и такой ситуации просто не возникает.
ЕМ>Кстати, давно уже есть подозрение, что ключом /W4, не говоря уже о /Wall, в MS пользуется очень ограниченная группа людей (и преимущественно на тестовых примерах), а подавляющее большинство ограничивается максимум /W3.
Не знаю, как в MS, а мы (не в MS) пользуемся /W4, и ещё некоторыми сверх того иногда. Про полный /Wall разделяю подозрение.
Русский военный корабль идёт ко дну!
Re[2]: Смысл предупреждения "declaration hides class member"
Здравствуйте, Alexander G, Вы писали:
AG>есть и мнение, что в целом бесполезный ворнинг.
Это явная глупость. Типичный пример: в функции-члене есть единичное использование переменной-члена, затем проект попадает к другому разработчику (или автор просто забывает об этой маловажной и неочевидной переменной), и в функцию добавляется локальная переменная или параметр с таким же именем.
AG>Многими принято соглашение об именовании, где члены данные именуются не так, как параметры, и такой ситуации просто не возникает.
Такие соглашения (и многие другие) порождены главным образом убожеством компиляторов, не умевших давать нужные предупреждения.
AG>Не знаю, как в MS, а мы (не в MS) пользуемся /W4, и ещё некоторыми сверх того иногда. Про полный /Wall разделяю подозрение.
Я с самого начала использования C/C++ подсел на полный набор предупреждений, глобально отключая только откровенно бесполезные для конкретного проекта, вроде "unreferenced inline function will be removed". А как только узнал про /Wall, стал его ставить по умолчанию везде. Много раз спасало от вдумчивого ковыряния в коде при поиске неявных ошибок.
Re: Смысл предупреждения "declaration hides class member"
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Мне одному кажется, что в таком варианте от предупреждения нет ни малейшего смысла, а лишь сплошной вред?
а в чём вред? По-моему, полезное предупреждение. Переименуйте переменную и явно укажите читающему, какая переменная берётся. Компилятору это конечно очевидно. А зачем человеку в этих хитросплетениях разбираться? Как минимум возникает вопрос: "может тут ошибка, и стоит брать именно С1::i1?"
Re[2]: Смысл предупреждения "declaration hides class member"
Здравствуйте, Евгений Музыченко, Вы писали:
SP>>Переименуйте переменную
ЕМ>Не хочу. Хочу, чтоб соблюдался принцип инкапсуляции.
Казалось бы, а причём тут именование переменных к инкапсуляции. Ворнинг правильный, обычно указывает на проблемы с кодстайлом. Возьмите подход из unreal engine, где у входных параметров пишется префикс "in".
Re[4]: Смысл предупреждения "declaration hides class member"
Здравствуйте, SaZ, Вы писали:
SaZ>Казалось бы, а причём тут именование переменных к инкапсуляции.
Именно — правильно реализованная инкапсуляция никак не должна ограничивать свободу именования переменных. Если член базового класса закрыт для потомков, то его имя (и вообще факт наличия) никак не должен конфликтовать с их кодом. Ошибки вроде "member 'xxx' is inaccessible" выдаются прежде всего с наводящей целью, чтобы разработчики не гадали, где теряется видимость.
SaZ>Ворнинг правильный, обычно указывает на проблемы с кодстайлом. Возьмите подход из unreal engine, где у входных параметров пишется префикс "in".
Типичный пример извращенного мышления — предлагать костыль там, где можно было бы обеспечить независимость.