Как элегантно преодолеть бессмысленные предупреждения компилятора C ++? - PullRequest
27 голосов
/ 15 ноября 2011

Этот вопрос не связан с каким-либо конкретным предупреждением компилятора, ниже приведен только пример.

В настоящее время, когда я хочу цикл, который проверяет условие выхода внутри:

 while( true ) {
    doSomething();
    if( condition() ) {
       break;
    }
    doSomethingElse();
}

Я не могу просто написать это в Visual C ++ - он выдаст предупреждение C4127 conditional expression is constant. Компилятор покажет мне это в лицо, хотя совершенно очевидно, что while(true) нельзя было написать случайно.

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

Обходной путь - использовать for(;;), но это глупо - зачем мне хотеть эту странную вещь вместо краткой элегантной идиоматики while(true)? Обходной путь 2 - использовать #pragma warning( suppress) перед строкой while( true ), но он добавляет огромный баннер, который в два раза больше, чем само while заявление. Обходной путь три - отключить C4127 для всего проекта (я видел, что это было сделано в реальном проекте), но затем все возможные полезные экземпляры C4127 также отключены.

Есть ли какой-нибудь элегантный способ избавиться от бессмысленного предупреждения?

Ответы [ 7 ]

28 голосов
/ 15 ноября 2011

Я бы написал for(;;), потому что это идиоматично.

Более новые версии Visual C ++ не такие идиотские, как предыдущие версии.предупреждения.Visual C ++ 10.0 компилирует код, который использует <windows.h>, на уровне предупреждений 4, без предупреждений.

Но если вы хотите отключить глупые предупреждения Visual C ++, взгляните на мой старый anti-sillywarnings header , который был создан при участии сообщества [comp.lang.c ++].

11 голосов
/ 15 ноября 2011

Я бы пошел с for(;;) даже без этого предупреждения. Это не глупо: это цикл без каких-либо условий, и это именно то, что вы хотите выразить.

Это кажется мне более логичным, чем использование цикла while и проверка того, что true по-прежнему истинно каждый раз в цикле (конечно, компилятор оптимизирует этот тест, поэтому это не повлияет на производительность).

6 голосов
/ 15 ноября 2011

Что может быть - реально осуществимо - больше элегантно, что одна строка:

 #pragma warning ( suppress : 4127 )

( Я не могу использовать это какЯ все еще на VS2005, где это не работает для всех предупреждений .)

Конечно, для вашего случая for(;;) может быть прагматическим подходом, но в целом

Как элегантно преодолеть бессмысленные предупреждения компилятора C ++?

Я бы сказал, отключить их для всего проекта .(там бессмысленно в конце концов).И, чтобы изменить

Как элегантно преодолеть ложно-положительных предупреждений компилятора C ++?

Я бы сказал, single линия препроцессора, кажется, уже в порядке.

3 голосов
/ 15 ноября 2011

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

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

Кстати, вы ищете способ подавления предупреждений без

  • Используйте прагму
  • Используйте некрасивый код
  • Использовать подавление для всего проекта

Это был бы очень скрытый метод подавления.

Если вам не нравится внешний вид прагмы, используйте

bool alwaysTrue = true; // to prevent compiler warning C4127
while (alwaysTrue) {
    ...
}
0 голосов
/ 12 декабря 2011

Я использую while (true, 1) для подавления этого предупреждения.

0 голосов
/ 15 ноября 2011

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

Пример цикла из вопроса можно записать так:

for (; testExitCondition();) 
  doSomething();

В более сложных случаях счетчик цикла может использоваться как состояние конечного автомата (каждое действие требуется для обновления состояние ):

for (int state = stateBegin; state == stateTerminate;) 
{
  switch (state) 
  {
    case stateBegin:
      //elaborate setup
      break;
    case state_1: 
      doSomething_1();
      break;
    case state_2: 
      doSomething_2();
      break;
    case state_n: 
      doSomething_n();
      break;
}

Мой любимый способ избежать бессмысленных предупреждений C ++ - использовать C #:)

По общему признанию это производит множество бессмысленных предупреждений C #, но ничто не идеально.

Черт возьми, посмотри на отрицательные голоса. Доказательство того, что C ++ вредит вашему чувству юмора.

0 голосов
/ 15 ноября 2011

Сделайте несколько забавных вставок токенов: если вы можете поменяться

while(true)

для

While(true)

, тогда просто сделайте следующее:

#define while_true for( ;; )
#define While(a) while_##a
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...