Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 03:12
Оценка: +1
В MS VC++ издавна есть предупреждение 4127 (conditional expression is constant). Удобная штука, помогает ловить ошибки вроде "if (Enabled && Allowed)", где один из операндов является константой, равной false. Но мешает использовать конструкции вроде "while (true)" или "do ... while (false)" — для них приходится делать костыли.

Сейчас обнаружил, что из компиляторов версии 19 его выпилили для явных констант. То есть, "while (true)" предупреждения не вызывает, но и "while (false)" или "if (false)" тоже проходят на ура, и никаких тебе "unreachable code". Самое смешное, что при отключенной оптимизации для них генерится что-то вроде

    xor    eax, eax
    je    SHORT $LN2@f

        <здесь код из if/while>

Принудительно включить предупреждение в этих случаях невозможно — ни /Wall, ни __pragma (warning) не помогают.

Это только MS так развлекается, или "по всей стране началось"?
MS VC++ visual c++ microsoft conditional expression constant warning true false while if
Re: Предупреждения о константном условии
От: Alexander G Украина  
Дата: 24.05.20 05:13
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>"while (false)" или "if (false)" тоже проходят на ура, и никаких тебе "unreachable code".


Предположение: может быть, это как-то связанно с введением if constexpr

ЕМ> Но мешает использовать конструкции вроде "while (true)" или "do ... while (false)" — для них приходится делать костыли.


Как по мне, не очень мешает
while(true) можно заменить на for( ; ; ) — это даже более идиоматичная конструкция

С do {...} while (false) сложнее, но можно заменить на костыль if constexpr(false) {} else { ... } , хотя есть нюанс, что while(false) требует ;

лучше бы оставили ворнинги.
Отредактировано 24.05.2020 5:23 Alexander G . Предыдущая версия . Еще …
Отредактировано 24.05.2020 5:22 Alexander G . Предыдущая версия .
Re[2]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 05:30
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Предположение: может быть, это как-то связанно с введением if constexpr


Как это может быть связано, кроме как кривой правкой кода компилятора?

AG>while(true) можно заменить на for( ; ; ) — это даже более идиоматичная конструкция


Согласен.

AG>С do {...} while (false) сложнее, но можно заменить на костыль if constexpr(false) {} else { ... } , хотя есть нюанс, что while(false) требует ;


Это вообще извращение. Я do...while (false) использую для организации выхода из блока по break, по причине нехватки соответствующих структурных средств. После появления __pragma стало возможным конструкцию с while (false), окруженную временным подавлением предупреждения, завернуть в макрос вроде WhileFalse. Теперь этого не требуется, но и возможность обнаруживать косяки в коде потеряна. Если руки дойдут — напишу им багрепорт.
Re[3]: Предупреждения о константном условии
От: Alexander G Украина  
Дата: 24.05.20 05:37
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Здравствуйте, Alexander G, Вы писали:


AG>>Предположение: может быть, это как-то связанно с введением if constexpr


ЕМ>Как это может быть связано, кроме как кривой правкой кода компилятора?


Ну кривая правка компилятора как вариант, причём и в варианте "упустили", и в варианте "поленились затыкать для constexpr, но оставить для обычного"

Как другой вариант, начали использовать в библиотеках, в том же STL, но оказалось, что if constexpr можно только с /std:c++17 или /std:c++latest, завернули constexpr, который с if в макро _CONSTEXPR_IF, ну и убрали ворнинг и для обычного if, в который этот макро разворачивается для C++14.
Re[4]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 05:55
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>Ну кривая правка компилятора как вариант, причём и в варианте "упустили", и в варианте "поленились затыкать для constexpr, но оставить для обычного"


Нашел, что они это упомянули в описании C4127. Однако, приведя столько примеров, не сообразили подумать и о false.

AG>Как другой вариант, начали использовать в библиотеках, в том же STL, но оказалось, что if constexpr можно только с /std:c++17 или /std:c++latest


По уму, им бы еще лет двадцать назад сделать условную компиляцию по простому константному условию (тому же sizeof). Множества проблем просто не возникло бы.
Re[3]: Предупреждения о константном условии
От: Alexander G Украина  
Дата: 24.05.20 07:27
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Это вообще извращение. Я do...while (false) использую для организации выхода из блока по break, по причине нехватки соответствующих структурных средств.


goto не предлагать?

Тогда такие альтернативные варианты (на случай, если ворнинг починят):
1.
    for (;;)
    {
       
       break;
    }


2.
    for (bool one_iteration_loop = true ; one_iteration_loop; one_iteration_loop = false)
    {

    }
Re[4]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 08:57
Оценка:
Здравствуйте, Alexander G, Вы писали:

AG>goto не предлагать?


Не.

AG>
AG>    for (;;)
AG>    {
AG>       break;
AG>    }
AG>

Это слишком чревато. Удалился случайно break в конце — и привет.

AG>
AG>    for (bool one_iteration_loop = true ; one_iteration_loop; one_iteration_loop = false)
AG>    {
AG>    }
AG>


А это избыточно. На случай, если починят, у меня уже есть

#define While(Cond) \
  __pragma (warning (suppress: 4127)) \
  while (Cond) \
Re[2]: Предупреждения о константном условии
От: Marty Пират  
Дата: 24.05.20 09:07
Оценка: +1
Здравствуйте, Alexander G, Вы писали:


AG>С do {...} while (false) сложнее, но можно заменить на костыль if constexpr(false) {} else { ... } , хотя есть нюанс, что while(false) требует ;



Так для этой точки с запятой ду-хастdo-while и городят, иначе в макросе можно просто блок сделать без всяких if'ов
Вам как-бы показали сцыкливое мурло российской оппозиции — вот оно
Автор: Министр Промышленности
Дата: 17.10.19
!
Re[3]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 09:17
Оценка:
Здравствуйте, Marty, Вы писали:

M>Так для этой точки с запятой ду-хастdo-while и городят, иначе в макросе можно просто блок сделать без всяких if'ов


Не понял, при чем здесь точка с запятой. Я do-while использую для проверки входных условий, чтобы не городить вложенные if'ы или последовательную проверку статусной переменной.
Re[4]: Предупреждения о константном условии
От: Marty Пират  
Дата: 24.05.20 09:20
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

M>>Так для этой точки с запятой ду-хастdo-while и городят, иначе в макросе можно просто блок сделать без всяких if'ов


ЕМ>Не понял, при чем здесь точка с запятой. Я do-while использую для проверки входных условий, чтобы не городить вложенные if'ы или последовательную проверку статусной переменной.


Как-то так:
#define MACRO(a)   \
    do             \
    {              \
        a++;       \
                   \
    } while(false) \
Вам как-бы показали сцыкливое мурло российской оппозиции — вот оно
Автор: Министр Промышленности
Дата: 17.10.19
!
Re[5]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 09:32
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>#define MACRO(a)   \
M>    do             \
M>    {              \
M>        a++;       \
M>                   \
M>    } while(false) \
M>


Опять не понял. Для чего этот "цикл" заворачивать в макрос?
Re[6]: Предупреждения о константном условии
От: Marty Пират  
Дата: 24.05.20 09:51
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:


ЕМ>Опять не понял. Для чего этот "цикл" заворачивать в макрос?


Это не цикл, завернутый в макрос, это длинный макрос, все строки которого завернуты в блок. А do-while там для того, чтобы вызывать нормально:

#define MACRO_A(a) \
    do             \
    {              \
        a++;       \
        a++;       \
        a++;       \
        a++;       \
        a++;       \
                   \
    } while(false) \

#define MACRO_B(a) \
    {              \
        a++;       \
        a++;       \
        a++;       \
        a++;       \
        a++;       \
                   \
    }

int main()
{
    int a = 0;

    MACRO_A(a); // Тут нормально вызывается, function-style
    MACRO_B(a)  // Тут криво, может поломать всякие парсеры/подсветки синтаксиса и тп
    MACRO_B(a); // Можно так, но ';' не обязательная, образует пустой оператор после блока
    if (a)
        MACRO_B(a); 
    else            // Тут поломается
        MACRO_A(a);
}


Я вообще думал, об этом все знают
Вам как-бы показали сцыкливое мурло российской оппозиции — вот оно
Автор: Министр Промышленности
Дата: 17.10.19
!
Re[7]: Предупреждения о константном условии
От: Евгений Музыченко Франция http://software.muzychenko.net/rus
Дата: 24.05.20 10:04
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>    if (a)
M>        MACRO_B(a); 
M>    else            // Тут поломается
M>        MACRO_A(a);
M>}
M>

M>Я вообще думал, об этом все знают

Я об этом теоретически знаю, но всегда ставлю скобки, чтобы не занимать мозг еще и такой ерундой. Поэтому оно и не вспоминается автоматически, а только при явном указании на.
Re[7]: Предупреждения о константном условии
От: Ops Россия  
Дата: 25.05.20 08:06
Оценка:
Здравствуйте, Marty, Вы писали:

M>
M>    if (a)
M>        MACRO_B(a); 
M>    else            // Тут поломается
M>        MACRO_A(a);
M>}
M>


M>Я вообще думал, об этом все знают


Писать всегда фигурные скобки в if, не?
Переубедить Вас, к сожалению, мне не удастся, поэтому сразу перейду к оскорблениям.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.