Подтвердить что ты не робот

Есть ли способ заставить VS2008 прекратить предупреждать меня о недостижимом коде?

У меня есть несколько вариантов конфигурации в моем приложении в строках

const bool ExecuteThis=true;
const bool ExecuteThat=false;

а затем код, который использует его как

if(ExecuteThis){ DoThis(); }
if(ExecuteThat){ DoThat(); } //unreachable code warning here

Дело в том, что мы можем сделать несколько разные релизы, а не ExecuteThis или ExecuteThat, и мы хотим иметь возможность использовать consts, чтобы у нас не было никаких скоростных штрафов от таких вещей во время выполнения. Но я устал видеть предупреждения о недостижимом коде. Я человек, который любит устранять все предупреждения, но я ничего не могу с этим поделать. Есть ли какой-то вариант, который я могу использовать, чтобы отключить эти предупреждения?

4b9b3361

Ответ 1

Чтобы отключить:

#pragma warning disable 0162

Для восстановления:

#pragma warning restore 0162

Подробнее о #pragma warning см. MSDN.

Обратите внимание, что компилятор С# оптимизирован настолько, чтобы не выдавать недостижимый код. Это называется удаление мертвого кода, и это одна из нескольких оптимизаций, которые Компилятор С# выполняет.

И вы не должны willy-nilly отключать предупреждения. Предупреждения являются симптомом проблемы. См. Этот ответ.

Ответ 2

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

Прежде чем перейти к тому, что при повторном чтении соответствует тому, что выглядит как разглагольствование, позвольте мне подчеркнуть, что для использования такого кода, похоже, не существует каких-либо ограничений производительности. Используя Reflector, чтобы проверить код, появляется код, который помечен как недостижимый, фактически не помещается в сборку вывода.

Он, однако, проверяется компилятором. Это само по себе может быть достаточно хорошей причиной, чтобы игнорировать мою напыщенность.

Другими словами, чистый эффект избавления от этого предупреждения заключается именно в том, что вы избавляетесь от предупреждения.

Также обратите внимание, что этот ответ - это мнение. Вы можете не согласиться с моим мнением и хотите использовать #pragma для маскировки предупреждающего сообщения, но, по крайней мере, иметь информированное мнение о том, что это делает. Если да, то кого волнует, что я думаю.

Сказав это, почему вы пишете код, который не будет достигнут?

Используете ли вы consts вместо "определяет"?

Предупреждение не является ошибкой. Это записка для вас, чтобы проанализировать этот фрагмент кода и выяснить, правильно ли вы сделали это. Обычно нет. В случае вашего конкретного примера вы намеренно компилируете код, который для вашей конкретной конфигурации никогда не будет выполнен.

Почему код существует? Он выполнит никогда.

Вы смущены тем, что на самом деле означает слово "константа"? Постоянное означает, что "это никогда не изменится, и если вы думаете, что это произойдет, это не постоянное". Это то, что есть константа. Он не будет, а не может и не должен меняться. Когда-нибудь.

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

Будет ли постоянная изменяться? Если это так, это, очевидно, не константа, а что-то, что зависит от типа вывода (Debug, Release), а это тип "#define", поэтому удалите его и используйте этот механизм. Это делает его более ясным, для людей, читающих ваш код, от чего зависит этот конкретный код. Visual Studio также будет серой код, если вы выбрали режим вывода, который не задает определение, поэтому код не будет компилироваться. Это то, что было сделано для описания компилятора.

С другой стороны, если константа не изменится, никогда, по какой-либо причине, удалите код, вам это не понадобится.

В любом случае, не становитесь жертвой легкого исправления, чтобы просто отключить это предупреждение для этого фрагмента кода, например, как аспирин, чтобы "исправить" ваши проблемы с задней болью. Это кратковременное исправление, но оно маскирует проблему. Исправьте основную проблему.

Чтобы закончить этот ответ, мне интересно, не существует ли совсем другого решения вашей проблемы.

Часто, когда я вижу код с предупреждением о недостижимом коде, он попадает в одну из следующих категорий:

  • Неверное (на мой взгляд) использование const по сравнению с компилятором #define, где вы в основном говорите компилятору: "Этот код, пожалуйста, скомпилируйте его, даже если я знаю, что он не будет использоваться".
  • Неправильно, как и в, просто неправильно, как в случае коммутатора, который имеет блок-блок, содержащий как бросок + разрыв.
  • Оставленный код из предыдущих итераций, где вы только коротко закодировали метод, добавив возврат в какой-то момент, а не удаляя (или даже комментируя) следующий код.
  • Код, который зависит от некоторых настроек конфигурации (т.е. действителен только во время отладки-сборки).

Если код, который у вас есть, не подпадает ни под одну из вышеуказанных настроек, каков конкретный случай, когда ваша константа изменится? Зная, что это может дать нам лучшие способы ответить на ваш вопрос о том, как с этим справиться.

Ответ 3

Как насчет использования инструкций препроцессора?

#if ExecuteThis
    DoThis();
#endif

#if ExecuteThat
    DoThat();
#endif

Ответ 4

Ну, #pragma, но это очень грубо. Интересно, будет ли ConditionalAttribute - т.е.

[Conditional("SOME_KEY")]
void DoThis() {...}
[Conditional("SOME_OTHER_KEY")]
void DoThis() {...}

Теперь вызовы DoThis/DoThat включаются, только если SOME_KEY или SOME_OTHER_KEY определены как символы в сборке ( "условные символы компиляции" ). Это также означает, что вы можете переключаться между ними, изменяя конфигурацию и определяя разные символы в каждом.

Ответ 5

Самый простой способ - прекратить писать недостижимый код: D #DontDoThat

Ответ 6

Тот факт, что у вас есть константы, объявленные в коде, говорит мне, что вы перекомпилируете свой код с каждой версией, которую вы делаете, вы не используете "contants" из вашего файла конфигурации.

Итак, решение прост:  - установить "константы" (флаги) из значений, хранящихся в вашем файле конфигурации  - используйте условную компиляцию для управления компиляцией, например:

#define ExecuteThis
//#define ExecuteThat

public void myFunction() {
#if ExecuteThis
    DoThis();
#endif
#if ExecuteThat
    DoThat();
#endif
}

Затем, когда вы перекомпилируете, вы просто раскомментируете правильный оператор #define, чтобы получить правильный бит скомпилированного кода. Есть один или два других способа объявить ваши условные флаговые компиляции, но это просто дает вам пример и где-то начать.

Ответ 7

Самый быстрый способ "просто избавиться от него" без изменения кода будет заключаться в использовании

#pragma warning disable 0162

В вашем пространстве имен, классе или методе, где вы хотите прервать это предупреждение.

Например, это больше не будет бросать предупреждение:

#pragma warning disable 0162
namespace ConsoleApplication4
{
  public class Program
  {
    public const bool something = false;

    static void Main(string[] args)
    {
        if (something) { Console.WriteLine(" Not something" ); }

    } 
 }

Однако будьте предупреждены, что NO METHOD внутри этого пространства имен снова вызовет предупреждение... и хорошо.. Предупреждения существуют по какой-то причине (что, если это произошло, когда вы НЕ планировали его недостижимость?)

Я полагаю, что безопаснее будет записывать переменные в файле конфигурации и читать их оттуда в начале программы, так что вам даже не нужно перекомпилировать, чтобы ваши разные версии/релизы! Просто измените файл приложения и перейдите: D.

о штрафе за скорость.. да.., делая это таким образом, запросит в скорости штраф... по сравнению с использованием const, но если вы действительно не беспокоитесь о том, что будете получать 1/100 миллисекунды больше.. Я бы пойдите для этого таким образом.

Ответ 8

Вот трюк:

    bool FALSE = false;
    if (FALSE) { ... 

Это предотвратит предупреждение. Подождите. Я знаю, что все это "Вы не должны использовать это, почему код не выполняется?". Ответ: Потому что во время разработки вам часто нужно настроить тестовый код. В конце концов вы избавитесь от него. Важно, чтобы код был там во время разработки, но не выполнялся все время.

Иногда вы хотите временно удалить выполнение кода для целей отладки.

Иногда вы хотите временно урезать выполнение функции. Вы можете использовать это, чтобы избежать предупреждений:

... код..        {bool TRUE = true; if (TRUE) return; }  ... больше кода...

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

Итак, вы можете спросить, почему это имеет значение? Ну, эти предупреждения очень раздражают, когда я нажимаю F4, чтобы перейти к первой ошибке, и сначала получите некоторые проклятые 10 предупреждений, и я глубоко вдаюсь в отладку.

Используйте #pragma, вы говорите. Хорошо, это было бы хорошей идеей, за исключением того, что я не могу найти способ сделать это глобально по всему моему проекту.. или таким образом, что будет работать с Unity3D, что и является кодом для С#. О, насколько полезной будет #include.

Ничего, используйте #if! Ну... да... но иногда они не то, что вы хотите. Они делают код грязным и нечитаемым. Вы должны скопировать код с ними в самый раз. Помещение if (false) перед блоком намного проще... нет необходимости разграничивать блок, скобки делают это.

То, что я делаю, это сделать доступным глобально доступным FALSE и TRUE и использовать их, поскольку мне нужно избегать ошибок.

И если я хочу проверить, действительно ли я их использую, я могу искать все ссылки или более грубо, но так же эффективно удалять их и, следовательно, заставлять смотреть на каждое появление этой маленькой трюки.