Re: MSVC C1061: compiler limit: blocks nested too deeply
От: so5team https://stiffstream.com
Дата: 18.10.25 06:00
Оценка: +4
Здравствуйте, Marty, Вы писали:

M>у меня длинный if else из порядка 200 двухсот таких условий.


Невозможно не вспомнить попытку
Автор: Marty
Дата: 02.06.25
донесения до вас одной простой мысли:

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-ов разбить на разные функции.
struct context_for_complex_condition {
  int _a, _b, _c, _d, _e, ...;
};
bool first_part_of_complex_condition(
    context_for_complex_condition & ctx) {
  if(ctx._a && ctx._b) {
    ...
    return true;
  }
  if(!(ctx._a && ctx._b) || ctx._c) {
    ...
    return true;
  }
  return false;
}
bool second_part_of_complex_condition(
    context_for_complex_condition & ctx) {
  if(!ctx._c && ctx._d) {
    ...
    return true;
  }
  if(!ctx._d || (ctx._e && ctx._f)) {
    ...
    return true;
  }
  return false;
}
... // Остальные части.
void long_function_as_marty_likes() {
  context_for_complex_condition ctx;
  ...
  if(first_part_of_complex_condition(ctx)) return;
  if(second_part_of_complex_condition(ctx)) return;
  ...
}
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: rg45 СССР  
Дата: 18.10.25 12:17
Оценка: +3
Здравствуйте, Marty, Вы писали:

M>Проверил идею: без макросов добавил пару if'ов:

M>
M>        else if (true)
M>        {
M>            return 0;
M>        }

M>        else if (false)
M>        {
M>            return 0;
M>        }
M>


А нафига тебе здесь 'else', когда в каждом 'if' у тебя 'return'? Просто удали их, и вся твоя вложенность превратится в простую последовательность независимых if-ов.
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 18.10.2025 12:21 rg45 . Предыдущая версия .
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 22.10.25 17:17
Оценка: :))
Здравствуйте, Евгений Музыченко, Вы писали:

M>>Но 8 вариантов компилятор уже не выдерживает


ЕМ>"И эти люди запрещают мне ковыряться в носу...".


Да хоть в говне ковыряйся
Маньяк Робокряк колесит по городу
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
От: rg45 СССР  
Дата: 18.10.25 13:39
Оценка: +1
Здравствуйте, Marty, Вы писали:

M>Но вроде бы return'ы не везде, и else if я сделал для однообразия. Но надо глянуть поточнее


Ну, попробуй поубирать хотя бы там, где можно, глядишь, проблема и рассосётся.
--
Справедливость выше закона. А человечность выше справедливости.
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: Went  
Дата: 20.10.25 06:25
Оценка: +1
Здравствуйте, Marty.
У меня в C# -> C++ трансляторе подобная проблема решается (в C# такого ограничения нет). Слишком длинная лестница преобразуется в
while (true)
{
  if (condition1)
  {
    // action1
    break;
  }
  .....
  if (conditionN)
  {
    // actionN
    break;
  }

  break;
}
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
От: serg_joker Украина  
Дата: 24.10.25 14:01
Оценка: +1
Здравствуйте, Евгений Музыченко, Вы писали:


M>>Но 8 вариантов компилятор уже не выдерживает

ЕМ>"И эти люди запрещают мне ковыряться в носу...".
Вы просто оба участвуете в спецолимпиаде, но в разных категориях.
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 24.10.25 14:36
Оценка: +1
Здравствуйте, serg_joker, Вы писали:

_>Вы просто оба участвуете в спецолимпиаде, но в разных категориях.


Угу, только он при этом всячески подчеркивает, что тенденции "развития" языка его вполне устраивают, и у него все якобы зашибись, но регулярно палится с такими вот примерами.
MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 17.10.25 22:25
Оценка:
Здравствуйте!

MSVC выдал сабжевую шляпу.

Я завернул некоторые одинаковые действия в макрос, копипастить не хотелось, думать, как шаблонить тоже — там три else if'а в макросе, из череды подобных else if'ов. Было два блока копипасты, отличающихся мелочами; пока их было два, всё устраивало, но понадобилось добавить ёще пяток аналогичных, решил в макрос завернуть, и получил такую ошибку.

При этом, если я коментирую новое добавление, оставляя только первые исходные два варианта, но только через макросы, то нормас.

Но 8 вариантов компилятор уже не выдерживает, проверил постепенным восстановлением закомментированного.

Проверил идею: без макросов добавил пару if'ов:
        else if (true)
        {
            return 0;
        }

        else if (false)
        {
            return 0;
        }


— компиляция ломается

у меня длинный if else из порядка 200 двухсот таких условий.

И мне бы его хотелось и дальше его увеличивать без проблем. Иначе кучу всего переделывать придётся. И не факт, что если я переделаю, то не вылезет ещё что-то подобное.

И чтоо делать?
Маньяк Робокряк колесит по городу
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: Muxa  
Дата: 18.10.25 05:40
Оценка:
M>И чтоо делать?

Тоже натыкались на это в одном из прошлых проектов. У нас в условиях интовая переменная сравнивалась с различными константами, что легко переделывалось в свитч-кейс.
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 18.10.25 10:11
Оценка:
Здравствуйте, 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 — в одном месте всё задаётся
Маньяк Робокряк колесит по городу
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
От: T4r4sB Россия  
Дата: 18.10.25 11:29
Оценка:
Здравствуйте, Marty, Вы писали:

M> || opt.setDescription("Set variable valie for conditions and substitutions"))

M>Обработка ключей командной строки.

Выдели это в метод

setVariableValieForConditionsAndSubstitutions()
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[4]: MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 18.10.25 11:42
Оценка:
Здравствуйте, T4r4sB, Вы писали:

TB>Здравствуйте, Marty, Вы писали:


M>> || opt.setDescription("Set variable valie for conditions and substitutions"))

M>>Обработка ключей командной строки.

TB>Выдели это в метод


TB>setVariableValieForConditionsAndSubstitutions()


И чем это поможет?

ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?
Маньяк Робокряк колесит по городу
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
От: so5team https://stiffstream.com
Дата: 18.10.25 12:24
Оценка:
Здравствуйте, 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
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 18.10.25 13:05
Оценка:
Здравствуйте, rg45, Вы писали:

R>А нафига тебе здесь 'else', когда в каждом 'if' у тебя 'return'? Просто удали их, и вся твоя вложенность превратится в простую последовательность независимых if-ов.


Но вроде бы return'ы не везде, и else if я сделал для однообразия. Но надо глянуть поточнее
Маньяк Робокряк колесит по городу
Re[5]: MSVC C1061: compiler limit: blocks nested too deeply
От: T4r4sB Россия  
Дата: 18.10.25 13:13
Оценка:
Здравствуйте, Marty, Вы писали:

M>И чем это поможет?


Тогда все ифы, что внутри этого блока, уйдёт в другую функцию. И вложенности станет меньше.

M>ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?


Просто обратил внимание, как ты мог подумать что-то другое.
Нет такой подлости и мерзости, на которую бы не пошёл gcc ради бессмысленных 5% скорости в никому не нужном синтетическом тесте
Re[6]: MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 18.10.25 13:22
Оценка:
Здравствуйте, T4r4sB, Вы писали:

M>>И чем это поможет?


TB>Тогда все ифы, что внутри этого блока, уйдёт в другую функцию. И вложенности станет меньше.


Внешний if else всё равно останется, а проблема именно в нём, имхо. Я для теста добавлял if else без вложенных if — ошибка воспроизводится.

Ну и отрефакторить 200+ блоков в отдельные функции — такое себе удовольствие


M>>ЗЫ К описке ты докопался в силу большого ко мне неуважения, или просто обратил моё внимание?


TB>Просто обратил внимание, как ты мог подумать что-то другое.


Ну ты любишь об этом напоминать

За исправление — спс
Маньяк Робокряк колесит по городу
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: _NN_  
Дата: 19.10.25 08:00
Оценка:
Здравствуйте, Marty, Вы писали:

M>Здравствуйте!


M>MSVC выдал сабжевую шляпу.

Это документированное ограничение MSVC: https://learn.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/fatal-error-c1061

Nesting of code blocks exceeds the limit of 128 nesting levels.



Кстати, это всё по стандарту.

https://landley.net/c99-draft.html

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)

-- 127 nesting levels of blocks

-- 63 nesting levels of conditional inclusion


Так, что код рефакторить придётся.
http://rsdn.nemerleweb.com
http://nemerleweb.com
Re[3]: MSVC C1061: compiler limit: blocks nested too deeply
От: sergii.p  
Дата: 21.10.25 09:23
Оценка:
Здравствуйте, 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
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 21.10.25 18:19
Оценка:
Здравствуйте, 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 — уже не помню, какой-то нюанс был
Маньяк Робокряк колесит по городу
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: Евгений Музыченко Франция https://software.muzychenko.net/ru
Дата: 22.10.25 11:01
Оценка:
Здравствуйте, Marty, Вы писали:

M>Но 8 вариантов компилятор уже не выдерживает


"И эти люди запрещают мне ковыряться в носу...".
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: Великий Мессия google
Дата: 22.10.25 15:36
Оценка:
у clang/clang-cl нет таких лимитов

на функции разбивай
Re[2]: MSVC C1061: compiler limit: blocks nested too deeply
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 22.10.25 17:17
Оценка:
Здравствуйте, Великий Мессия, Вы писали:

ВМ>у clang/clang-cl нет таких лимитов


ВМ>на функции разбивай


Да ну, возни много
Маньяк Робокряк колесит по городу
Re: MSVC C1061: compiler limit: blocks nested too deeply
От: flаt  
Дата: 23.10.25 17:57
Оценка:
Здравствуйте, Marty, Вы писали:

M>И чтоо делать?


Не писать говнокод. И не писать велосипеды заодно.
Re[4]: MSVC C1061: compiler limit: blocks nested too deeply
От: serg_joker Украина  
Дата: 24.10.25 14:40
Оценка:
Здравствуйте, Евгений Музыченко, Вы писали:

ЕМ>Угу, только он при этом всячески подчеркивает, что тенденции "развития" языка его вполне устраивают, и у него все якобы зашибись, но регулярно палится с такими вот примерами.

Тут я полностью согласен.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.