Вырезанный воспроизводимый тестовый пример, для обновления VS2015 2, следующий. Мы пытались построить с "Уровнем предупреждения 4", и мы рассматриваем предупреждения как фатальные ошибки, чтобы улучшить шансы заметить указанные предупреждения. Я надеюсь, что кто-то из сообщества уже столкнулся с этим и нашел разумное решение.
Это может оказаться слишком локализованным, если никто другой не видел эквивалентную проблему, поэтому я хотел бы отметить, что основной вопрос заключается в том, "как плохо следует калечить кодовую базу, чтобы избежать слабых предупреждений компилятора" или, что то же самое, как следует сообщать об ошибках компилятору, который теряет отчеты об ошибках ".
#ifdef _WIN32
#pragma warning( push )
#pragma warning( disable : 4702 ) // As suggested by comments
#endif
template <class Type>
void func (Type t)
{
t.func ();
t.func ();
}
#ifdef _WIN32
#pragma warning( pop )
#endif
struct NoThrow
{
void func () {}
};
struct Throws
{
void func () {throw 1;}
};
int main ()
{
NoThrow nt;
func (nt);
Throws t;
func (t);
}
Это вызывает недопустимые предупреждения кода. Шаблонная функция выглядит разумной сама по себе, но для одного конкретного экземпляра компилятор может определить, что второй t.func() мертв, поэтому он предупреждает о недоступном коде.
Это похоже на довольно четкое качество выполнения проблемы для VS2015, поэтому мы открыли отчет об ошибке здесь.
Мы получили некоторые рекомендации от Microsoft,
К сожалению, бэкэнд компилятора (откуда возникло это предупреждение) не имеет реальной концепции создания экземпляров шаблонов в качестве экземпляров одной функции шаблона. Они все просто функции с похожими именами, если они когда-либо потрудились сравнить (украшенные) имена друг с другом. Который никогда не делает. Таким образом, он видит здесь одну функцию с некоторым недостижимым кодом, о котором он предупреждает, и другую функцию без недостижимого кода, чего нет. Эта концепция "предупреждения о перекрестных функциях", которую вы предлагаете, где мы собираем и сравниваем данные по различным установкам шаблонов и только предупреждаем, что это или нет, является чрезвычайно сложным в чистом двоичном коде LTCG и невозможным в противном случае.
Рассмотрим шаблон Foo в заголовке foo.h. Предположим, что a.cpp включает в себя и создает Foo с недостижимым кодом, а затем b.cpp включает его и создает Foo без недостижимого кода. Вы предполагаете, что в a.cpp Foo не следует предупреждать, удалите недостижимый код, потому что Foo существует без недостижимого кода. Но Foo скомпилирован в другом файле, в другом процессе, в другом вызове cl.exe и наиболее неудобно в будущем. Очевидно, что компилятор не имеет возможности достичь в будущем еще нерожденного процесса и извлекать информацию, необходимую для расчета, если он должен предупреждать или нет.
Единственный реальный жизнеспособный вариант, который мы имеем здесь, заключается в том, чтобы отключить недопустимое предупреждение для всех шаблонов, которое я буду честным, не произойдет, пока мы не убедимся, что нанесенный вред больше, чем хорошее (это чистая плохая). Предупреждения имеют ложные срабатывания, это происходит. Я попытаюсь подумать о других параметрах и посмотреть номер строки/файла.
Вышеуказанная ссылка может быть недоступна, но поскольку Интернет поставляется с кешами, вы можете увидеть копию здесь или найти свой собственный, используя 2744730 и создание некорректно-недостижимого кода-предупреждения-в-шаблоне.
Итак, если мы предположим, что базовая модель создания экземпляра шаблона предназначена для удаления копий функций, то подвергает их анализу тех же самых предупреждений, что и любой другой, как мы можем избежать предупреждения о мертвом коде? Я в настоящее время разрывается между добавлением тегов на десятки или около того шаблонов, которые в настоящее время затронуты или отключены предупреждения по всему миру.
edit: Прямая ссылка, похоже, снова живая.