Вимкнути єдину помилку попередження


115

Чи є спосіб відключити лише один попереджувальний рядок у файлі cpp за допомогою візуальної студії?

Наприклад, якщо я вловлю виняток і не обробляю його, я отримую помилку 4101 (невіднесена локальна змінна). Чи є спосіб проігнорувати це саме в цій функції, але в іншому випадку повідомте про це в блоці компіляції? На даний момент я ставлю #pragma warning (disable : 4101)вгорі файл, але це очевидно просто вимикає його для всього блоку.


19
якщо ви згадаєте лише тип і не назвете виняток, попередження не буде. Напр catch (const std::exception& /* unnamed */) {.... }. Це не відповідає на ваше запитання, але може вирішити вашу проблему.
Sjoerd

Відповіді:


182
#pragma warning( push )
#pragma warning( disable : 4101)
// Your function
#pragma warning( pop ) 

1
@Cookie: так, він працює для будь-якого фрагмента коду, який проходить через компілятор.
Matteo Italia

Більш недавню, стислу відповідь дивіться у відповіді Деніела Сієтера нижче.
Дан Ніссенбаум

4
clangздається, не підтримують цю Прагма, але ви можете досягти того ж ефекту #pragma clang diagnostic push, #pragma clang diagnostic ignored "-Wunused-variable"і #pragma clang diagnostic pop. Дивіться "Контроль діагностики через Прагми" в Посібнику користувача Clang
rampion

Оскільки я користуюсь цією функцією нечасто, коли я це роблю, я зазвичай запускаю цю сторінку, щоб нагадати про синтаксис. Я просто ставлю це заклик до застарілої функції, яка ніколи не може оновлюватися, щоб попередження не дратувало мене в списках компілятора, які я релігійно сканую.
Девід А. Грей

Для Visual Studio аргументом командного рядка є /wd4101. Зауважте, що :між прапором та цифрою між нормами немає норми , і ви не можете скласти список цифр, розділених комами. Для інших компіляторів це може бути /nowarn:4101замість цього.
Джессі Чисгольм

89

Якщо ви хочете придушити попередження лише в одному рядку коду, ви можете використовувати suppress специфікатор попередження :

#pragma warning(suppress: 4101)
// here goes your single line of code where the warning occurs

Для одного рядка коду це працює так само, як писати наступне:

#pragma warning(push)
#pragma warning(disable: 4101)
// here goes your code where the warning occurs
#pragma warning(pop)

8
Дуже корисний! На жаль, він не працює для жодного рядка, який включає заголовка, який генерує попередження.
Марко Попович

2
@MarkoPopovic: Специфікатор suppressпрацює на одному, попередньо обробленому рядку коду. Якщо наступний рядок #pragma warning(suppress: ...)- це #includeдиректива (яка розширює файл, на який посилається його параметр, у поточну одиницю компіляції), ефект застосовується лише до першого рядка цього файлу. Це має бути очевидним, оскільки попередження створюються компілятором. Компілятор працює над попередньо обробленим кодом.
Неочікуваний

@IInspectable В цьому випадку я б назвав це після обробки рядка коду. попередньо оброблений означає, що його ще не перекладено препроцесором.
void.pointer

2
@voi: Закінчення "-ed" означає минулий дієприкметник . Він використовується, щоб виразити, що щось закінчилося в минулому. «Попередньо оброблені» лінія являє собою лінію , яка була повністю оброблена.
IIнеочікуваний

29

#pragma push / pop часто є рішенням для подібних проблем, але в цьому випадку, чому б ви просто не видалити незв'язану змінну?

try
{
    // ...
}
catch(const your_exception_type &) // type specified but no variable declared
{
    // ...
}

6
Це не відповідає на питання. Зрозуміло, це може вирішити проблему ОП, але не допоможе майбутнім читачам простішим запитанням: "як вимкнути конкретне попередження для певної частини коду?"
Sjoerd

1
@Sjoerd: троє людей вже відповіли на "офіційне запитання", яке можуть шукати інші, тому натомість я спробував прочитати між рядків і вирішити його актуальну проблему (приїхавши через хвилину після вашого коментаря :P).
Matteo Italia

11
@Sjoerd, як майбутній читач, я свідчу, що ця відповідь насправді допомогла мені.
Молот

2
@ Molot: як минулий письменник, я радий, що це допомогло. =)
Маттео Італія

9

Використовуйте #pragma warning ( push ), потім #pragma warning ( disable ), введіть свій код, а потім використовуйте, #pragma warning ( pop )як описано тут :

#pragma warning( push )
#pragma warning( disable : WarningCode)
// code with warning
#pragma warning( pop ) 

8

Приклад:

#pragma warning(suppress:0000)  // (suppress one error in the next line)

Ця прагма діє для C ++, починаючи з Visual Studio 2005.
https://msdn.microsoft.com/en-us/library/2c8f766e(v=vs.80).aspx

Прагма НЕ дійсна для C # через Visual Studio 2005 через Visual Studio 2015.
Помилка: "Очікуване відключення або відновлення".
(Я думаю, вони ніколи не стикалися з реалізацією suppress...)
https://msdn.microsoft.com/en-us/library/441722ys(v=vs.140).aspx

C # потрібен інший формат. Це виглядатиме так (але не працює):

#pragma warning suppress 0642  // (suppress one error in the next line)

Замість того suppress, ви повинні disableі enable:

if (condition)
#pragma warning disable 0642
    ;  // Empty statement HERE provokes Warning: "Possible mistaken empty statement" (CS0642)
#pragma warning restore 0642
else

Це так негарно, я вважаю, що розумніше просто переробити його:

if (condition)
{
    // Do nothing (because blah blah blah).
}
else

5

Замість того , щоб покласти його на верхній частині файлу (або навіть заголовок файлу), просто перенесіть код в питанні з #pragma warning (push), #pragma warning (disable)і узгодженням #pragma warning (pop), як показано тут .

Хоча є й інші варіанти, в тому числі #pramga warning (once).


5

Можна також використовувати UNREFERENCED_PARAMETERвизначені в WinNT.H. Визначення просто:

#define UNREFERENCED_PARAMETER(P)          (P)

І використовувати його так:

void OnMessage(WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(wParam);
    UNREFERENCED_PARAMETER(lParam);
}

Навіщо використовувати його, ви можете стверджувати, що ви можете просто опустити ім'я змінної. Ну, є випадки (різні конфігурації проекту, налагодження / випуск версій), де змінна може бути реально використана. В іншій конфігурації ця змінна стоїть невикористаною (і, отже, попередженням).

Деякий аналіз статичного коду може все-таки попереджати про це нечуттєве твердження ( wParam;). У цьому випадку ви можете використовувати те, DBG_UNREFERENCED_PARAMETERщо є тим же, що і UNREFERENCED_PARAMETERв налагодженнях, а також P=Pу версії.

#define DBG_UNREFERENCED_PARAMETER(P)      (P) = (P)

1
зауважте, що оскільки на C ++ 11 у нас є [[maybe_unused]]атрибут
metablaster

2

Якщо ви хочете відключити unreferenced local variableзапис, у якомусь заголовку

template<class T>
void ignore (const T & ) {}

і використовувати

catch(const Except & excpt) {
    ignore(excpt); // No warning
    // ...  
} 

2
Виклик функції, просто щоб придушити попередження? Чому б вам не зробити це замість: (void)unusedVar;?
Наваз

@Nawaz: Я думаю, що (void)unusedVar;?це не відповідає стандарту C ++.
Олексій Малістов

2
Це вираз, цінність якого нічого. У C ++ ви навіть можете це зробити static_cast<void>(unusedVar).
Наваз


2
§5.2.9 / 4 говорить, Any expression can be explicitly converted to type “cv void.” The expression value is discardedзгідно з яким можна писати static_cast<void>(unusedVar)і static_cast<const void>(unusedVar)і static_cast<volatile void>(unusedVar). Усі форми дійсні. Сподіваюся, це прояснить ваші сумніви.
Наваз

2

У певних ситуаціях у вас повинен бути названий параметр, але ви не використовуєте його безпосередньо.
Наприклад, я наткнувся на нього на VS2010, коли 'e' використовується лише всередині decltypeоператора, компілятор скаржиться, але ви повинні мати названу змінну e.

Усі вищезазначені непропозиції #pragmaзводяться до простого додавання одного твердження:

bool f(int e)
{ 
   // code not using e
   return true;
   e; // use without doing anything
}

1
зараз (у компіляторі MS VS2015) це спричиняє недоступний код
C4702

2

як згадується @rampion, якщо ви перебуваєте в clang gcc, попередження мають по імені, а не по номеру, і вам потрібно буде зробити:

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-variable"
// ..your code..
#pragma clang diagnostic pop

ця інформація походить звідси

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.