В 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 так развлекается, или "по всей стране началось"?
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>"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) требует ;
Здравствуйте, 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. Теперь этого не требуется, но и возможность обнаруживать косяки в коде потеряна. Если руки дойдут — напишу им багрепорт.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Здравствуйте, Alexander G, Вы писали:
AG>>Предположение: может быть, это как-то связанно с введением if constexpr
ЕМ>Как это может быть связано, кроме как кривой правкой кода компилятора?
Ну кривая правка компилятора как вариант, причём и в варианте "упустили", и в варианте "поленились затыкать для constexpr, но оставить для обычного"
Как другой вариант, начали использовать в библиотеках, в том же STL, но оказалось, что if constexpr можно только с /std:c++17 или /std:c++latest, завернули constexpr, который с if в макро _CONSTEXPR_IF, ну и убрали ворнинг и для обычного if, в который этот макро разворачивается для C++14.
Здравствуйте, Alexander G, Вы писали:
AG>Ну кривая правка компилятора как вариант, причём и в варианте "упустили", и в варианте "поленились затыкать для constexpr, но оставить для обычного"
Нашел, что они это упомянули в описании C4127. Однако, приведя столько примеров, не сообразили подумать и о false.
AG>Как другой вариант, начали использовать в библиотеках, в том же STL, но оказалось, что if constexpr можно только с /std:c++17 или /std:c++latest
По уму, им бы еще лет двадцать назад сделать условную компиляцию по простому константному условию (тому же sizeof). Множества проблем просто не возникло бы.
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Это вообще извращение. Я do...while (false) использую для организации выхода из блока по break, по причине нехватки соответствующих структурных средств.
goto не предлагать?
Тогда такие альтернативные варианты (на случай, если ворнинг починят):
1.
Здравствуйте, Marty, Вы писали:
M>Так для этой точки с запятой ду-хастdo-while и городят, иначе в макросе можно просто блок сделать без всяких if'ов
Не понял, при чем здесь точка с запятой. Я do-while использую для проверки входных условий, чтобы не городить вложенные if'ы или последовательную проверку статусной переменной.
Здравствуйте, Евгений Музыченко, Вы писали:
M>>Так для этой точки с запятой ду-хастdo-while и городят, иначе в макросе можно просто блок сделать без всяких if'ов
ЕМ>Не понял, при чем здесь точка с запятой. Я do-while использую для проверки входных условий, чтобы не городить вложенные if'ы или последовательную проверку статусной переменной.
M> if (a)
M> MACRO_B(a);
M> else// Тут поломается
M> MACRO_A(a);
M>}
M>
M>Я вообще думал, об этом все знают
Я об этом теоретически знаю, но всегда ставлю скобки, чтобы не занимать мозг еще и такой ерундой. Поэтому оно и не вспоминается автоматически, а только при явном указании на.