S>Варианты? Например, вы слишком сильно интеллектуально развиты, чтобы делать простые удобные вещи для простых людей. Вам не сложно написать и сопровождать шаблон функции на 700 строк. Значит ваша целевая аудитория такие же очень умные люди, как и вы, коих очень и очень мало.
S>Либо, напростив, вы недостаточно умны, чтобы понять, что не должно быть шаблона функции на 700 строк, и не смочь найти вариант от этого избавиться.
S>Оба варианта так себе.
Не вижу особых проблем с функцией на 700 строк. Ещё претензии есть?
Сперва вы не видели проблем в функциях на 700 строк, потом с if else на 200 стравнений, а затем компилятор сдается и говорит "всё, я так больше не могу".
M>И чтоо делать?
Наверное, можно перестать считать форумчан телепатами, которые знают что и как вы делаете. Не видя кода невозможно дать вменяемый совет.
Пример из недавнего: был набор из if else, который и не нравился внешне, и несколько пессимизировал скорость работы кода. Что-то вроде:
if(A && B && C && D) {...}
else if(!A && B && C && D) {...}
else if(A && !B && C && D) {...}
else if(A && B && !C && D) {...}
else if(A && B && C && !D) {...}
Это дело удалось преобразовать в битовую маску (т.е. результат A, B, C, D был отдельным битиком в unsigned-е), что привело к более читаемому и чуть быстрее работающему switch-у:
switch(combine(A, B, C, B)) {
case 0b1111: ... break;
case 0b0111: ... break;
case 0b1011: ... break;
case 0b1101: ... break;
...
}
Но вряд ли мне что-то подобное кто-либо посоветовал бы, если бы я не показал исходное безобразие на if-ах.
В качестве общей абстрактной рекомендации можно разве что сказать, что если у вас что-то подобное:
void long_function_as_marty_likes() {
int a, b, c, d, e, f, g, ...;
...
if(a && b) {...}
else if(!(a && b) || c) {...}
else if(!c && d) {...}
else if(!d || (e && f)) {...}
... // и еще 196 штук.
}
То можно попробовать вынести контекст (т.е. a, b, c и пр.) в отдельную структуру, а последовательность if-ов разбить на разные функции.
А нафига тебе здесь 'else', когда в каждом 'if' у тебя 'return'? Просто удали их, и вся твоя вложенность превратится в простую последовательность независимых if-ов.
--
Справедливость выше закона. А человечность выше справедливости.
M>>Но 8 вариантов компилятор уже не выдерживает ЕМ>"И эти люди запрещают мне ковыряться в носу...".
Вы просто оба участвуете в спецолимпиаде, но в разных категориях.
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
Здравствуйте, serg_joker, Вы писали:
_>Вы просто оба участвуете в спецолимпиаде, но в разных категориях.
Угу, только он при этом всячески подчеркивает, что тенденции "развития" языка его вполне устраивают, и у него все якобы зашибись, но регулярно палится с такими вот примерами.
MSVC C1061: compiler limit: blocks nested too deeply
Я завернул некоторые одинаковые действия в макрос, копипастить не хотелось, думать, как шаблонить тоже — там три else if'а в макросе, из череды подобных else if'ов. Было два блока копипасты, отличающихся мелочами; пока их было два, всё устраивало, но понадобилось добавить ёще пяток аналогичных, решил в макрос завернуть, и получил такую ошибку.
При этом, если я коментирую новое добавление, оставляя только первые исходные два варианта, но только через макросы, то нормас.
Но 8 вариантов компилятор уже не выдерживает, проверил постепенным восстановлением закомментированного.
Проверил идею: без макросов добавил пару if'ов:
else if (true)
{
return 0;
}
else if (false)
{
return 0;
}
— компиляция ломается
у меня длинный if else из порядка 200 двухсот таких условий.
И мне бы его хотелось и дальше его увеличивать без проблем. Иначе кучу всего переделывать придётся. И не факт, что если я переделаю, то не вылезет ещё что-то подобное.
Тоже натыкались на это в одном из прошлых проектов. У нас в условиях интовая переменная сравнивалась с различными константами, что легко переделывалось в свитч-кейс.
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
Здравствуйте, Muxa, Вы писали:
M>>И чтоо делать?
M>Тоже натыкались на это в одном из прошлых проектов. У нас в условиях интовая переменная сравнивалась с различными константами, что легко переделывалось в свитч-кейс.
У меня портянка из такого:
else if ( opt.setParam("VAR:VAL")
|| opt.isOption("set-var") || opt.isOption("set-condition-var") || opt.isOption('C')
|| opt.setDescription("Set variable valie for conditions and substitutions"))
{
if (argsParser.hasHelpOption) return 0;
if (!opt.hasArg())
{
LOG_ERR<<"Setting condition variable requires argument (--set-condition-var)\n";
return -1;
}
auto optArg = opt.optArg;
if (!appConfig.addConditionVar(optArg))
{
LOG_ERR<<"Setting condition variable failed, invalid argument: '" << optArg << "' (--set-condition-var)\n";
return -1;
}
return 0;
}
Обработка ключей командной строки.
На какой-нибудь map с хэндлерами не переделать, потому что у меня в режиме --help пробегается по этим условиям и собирает выдаваемую потом информацию. Тут в if сразу и длинный ключ set-var задаётся, и короткий C, и подсказка по формату значения VAR:VAL и описание опции Set variable valie for conditions and substitutions — в одном месте всё задаётся
Здравствуйте, T4r4sB, Вы писали:
TB>Здравствуйте, Marty, Вы писали:
M>> || opt.setDescription("Set variable valie for conditions and substitutions")) M>>Обработка ключей командной строки.
TB>Выдели это в метод
TB>setVariableValieForConditionsAndSubstitutions()
И чем это поможет?
ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?
Здравствуйте, Marty, Вы писали:
M>На какой-нибудь map с хэндлерами не переделать, потому что у меня в режиме --help пробегается по этим условиям и собирает выдаваемую потом информацию. Тут в if сразу и длинный ключ set-var задаётся, и короткий C, и подсказка по формату значения VAR:VAL и описание опции Set variable valie for conditions and substitutions — в одном месте всё задаётся
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
Здравствуйте, rg45, Вы писали:
R>А нафига тебе здесь 'else', когда в каждом 'if' у тебя 'return'? Просто удали их, и вся твоя вложенность превратится в простую последовательность независимых if-ов.
Но вроде бы return'ы не везде, и else if я сделал для однообразия. Но надо глянуть поточнее
Здравствуйте, Marty, Вы писали:
M>И чем это поможет?
Тогда все ифы, что внутри этого блока, уйдёт в другую функцию. И вложенности станет меньше.
M>ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?
Просто обратил внимание, как ты мог подумать что-то другое.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[6]: MSVC C1061: compiler limit: blocks nested too deeply
Здравствуйте, T4r4sB, Вы писали:
M>>И чем это поможет?
TB>Тогда все ифы, что внутри этого блока, уйдёт в другую функцию. И вложенности станет меньше.
Внешний if else всё равно останется, а проблема именно в нём, имхо. Я для теста добавлял if else без вложенных if — ошибка воспроизводится.
Ну и отрефакторить 200+ блоков в отдельные функции — такое себе удовольствие
M>>ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?
TB>Просто обратил внимание, как ты мог подумать что-то другое.
The implementation shall be able to translate and execute at least one program that contains at least one instance of every one of the following limits:12)
Здравствуйте, Marty, Вы писали:
M>У меня портянка из такого: M>
M>else if ( opt.setParam("VAR:VAL")
M> || opt.isOption("set-var") || opt.isOption("set-condition-var") || opt.isOption('C')
M> || opt.setDescription("Set variable valie for conditions and substitutions"))
M>
просто стало интересно. Методы setParam и setDescription получается выдают false при успешном завершении? Иначе оно должно проваливаться в этот блок при любой другой опции
Re[4]: MSVC C1061: compiler limit: blocks nested too deeply
Здравствуйте, sergii.p, Вы писали:
M>>У меня портянка из такого: M>>
M>>else if ( opt.setParam("VAR:VAL")
M>> || opt.isOption("set-var") || opt.isOption("set-condition-var") || opt.isOption('C')
M>> || opt.setDescription("Set variable valie for conditions and substitutions"))
M>>
SP>просто стало интересно. Методы setParam и setDescription получается выдают false при успешном завершении? Иначе оно должно проваливаться в этот блок при любой другой опции
Да, все методы всегда выдают false, кроме isOption, это позволяет пробежаться по всем этим методам, чтобы они заполнили поля внутренней структуры с инфой по опции.
setParam и isOption сбрасывают собранное предыдущим if, и начинают новый элемент. setParam идёт раньше, в нём разные перегрузки задают тип параметра опции, ничего дополнительно не надо прописывать. Почему он даже раньше isOption — уже не помню, какой-то нюанс был
Здравствуйте, Евгений Музыченко, Вы писали:
ЕМ>Угу, только он при этом всячески подчеркивает, что тенденции "развития" языка его вполне устраивают, и у него все якобы зашибись, но регулярно палится с такими вот примерами.
Тут я полностью согласен.