С#: нужно ли восстановление предупреждения прагмы?

Из msdn я получаю следующее:

#pragma warning disable warning-list
#pragma warning restore warning-list

В примерах используются как disable, так и restore. Нужно ли restore, если я хочу отключить его для всего файла?

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


person Svish    schedule 17.02.2009    source источник


Ответы (3)


Если вы не восстанавливаете, отключение активно для оставшейся части файла.

Интересно, что такое поведение не определено в спецификация языка. (см. раздел 9.5.8). Однако раздел 9.5.1, посвященный символам условной компиляции, указывает на это «поведение до конца файла».

Символ остается определенным до тех пор, пока не будет обработана директива #undef для того же символа или пока не будет достигнут конец исходного файла.

Учитывая, что «препроцессор» на самом деле является частью фазы лексического анализа компиляции, вполне вероятно, что такое поведение является эффективным контрактом для Microsoft и всех других реализаций в обозримом будущем (тем более, что альтернатива будет чрезвычайно сложной и недетерминированной). в порядке компиляции исходного файла)

person ShuggyCoUk    schedule 17.02.2009
comment
В итоге: поведение не определено, поэтому нам нужно восстановить - person Julian; 18.05.2015
comment
Предположение о конце исходного файла не применяется к частичным классам, разделенным на несколько файлов... - person McGuireV10; 13.10.2018
comment
@ McGuireV10 McGuireV10 Вы имеете в виду, что прагма будет или не будет действовать для частичных классов в других файлах? - person StackOverthrow; 03.12.2018
comment
@TKK может показаться неопределенным, потому что это зависит от порядка, в котором компилятор обрабатывает файлы. Он вступает в силу всякий раз, когда компилятор сталкивается с ним, и остается в силе до тех пор, пока не будет явно отключен. Конец файла не применяется к частичным файлам. Вы определенно хотите отключить и снова включить в каждом файле, где вам это нужно. - person McGuireV10; 04.12.2018
comment
Ссылка на спецификацию языка устарела. - person Pang; 19.04.2021

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

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

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

person Nir    schedule 17.02.2009
comment
Вы указали один вариант использования и пришли к выводу, что все остальные варианты использования одинаковы. Кроме того, я думаю, что это должен был быть комментарий, а не ответ. - person Micha Wiedenmann; 17.08.2015
comment
@MichaWiedenmann - я пытался объяснить на примере, я мог бы написать, что иногда у вас есть два предупреждения одного типа в одном и том же файле, где первое является ложным срабатыванием, а второе - настоящей ошибкой - это был бы лучший ответ? на мой взгляд, нет, люди будут утверждать, что в реальном мире нет вариантов использования (если они не перестанут читать при ложном срабатывании) - person Nir; 17.08.2015

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

#pragma warning disable 649
struct MyInteropThing
{
    int a;
    int b;
}
#pragma warning restore 649

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

Поле «поле» никогда не назначается и всегда будет иметь значение по умолчанию «значение».

Но я не хочу, чтобы весь файл не остался без проверки.

person John Leidegren    schedule 17.02.2009
comment
Что делать, если предупреждение уже отключено аргументом командной строки? Вы в конечном итоге восстановите то, что не должны. - person drowa; 27.10.2016
comment
@drowa тогда предполагает, что вам вообще не нужно отключение. Насколько мне известно, в компиляторе C# нет ничего эквивалентного C++ push/pop. Так что лучше от этого не будет. - person John Leidegren; 28.10.2016