LINUX.ORG.RU

Кошерный выход из вложенных циклов в этих ваших плюсах

 


0

1

Как я понимаю, никакого подобия php-шных break/continue с аргументом в плюсах нет, посему для всех извращённых случаев рекомендуется использовать goto. Ну так вот банальнейший пример: один цикл вложен в другой, во вложенном условие, по которому надо перейти на следующий шаг внешнего цикла. Всё бы ничего, но КАКОЙ НАРЕДЬКИ goto в условии выкидывает SIGFPE? Это баг в g++ или нормальное поведение? В условии проверяется остаток деления long на long, деления на ноль ТОЧНО нет, без goto отрабатывает нормально. Метку ставил перед циклом и перед пустым операндом в его конце — монопенисуально. Что характерно, если перед этими циклами разместить, например, отладочный вывод через cout — он не отображается до выкидывания SIGFPE. gdb ругается именно на строку с условием.

//Если чего, полный код вот, в качестве аргументов можно 2 и 2 заюзать, например.

////Внесите Царя, пожалуйста.

★☆

Последнее исправление: stave (всего исправлений: 1)

goto сам по себе не должен приводить к падениям, ищи ошибку в смежных местах в своем коде.

Может ты проскакиваешь инициализацию переменной, которой потом пользуешься, и всё падает.

А вообще лучший выход из вложенного цикла в плюсах - это return.

yoghurt ★★★★★
()

Ты там, часом, на ноль не делишь?

anonymous
()

Метка с goto работают как надо, у тебе деление на ноль в i%primes[j] при i = 2, j = 1, primes[] = {2, 0, 0, ...}. Открой для себя gdb и прочти уже K&R. Алсо можно обойтись и без goto, бери пример с функциональщиков, благо gcc TCO очень даже умеет.

mix_mix ★★★★★
()

Вместо

goto c;
достаточно
break;

И да, про ноль уже сказали.

FIL ★★★★
()
Program received signal SIGFPE, Arithmetic exception.
0x00000000004009b5 in main (argc=3, argv=0x7fffffffda68) at test.c:21
21                                  if (i%primes[j])
EXL ★★★★★
()

Это гогнокод в лучшем случае сишный. В плюсах для второго цикла есть std::find_if() и вместо массивов std::vector

mashina ★★★★★
()

goto в условии выкидывает SIGFPE? Это баг в g++ или нормальное поведение?

SIGFPE
The SIGFPE signal is sent to a process when it executes an erroneous arithmetic operation, such as division by zero (the name «FPE», standing for floating-point exception, is a misnomer as the signal covers integer-arithmetic errors as well).[2]

что тебе не понятно?

Stil ★★★★★
()
Ответ на: комментарий от mashina

Это гогнокод в лучшем случае сишный. В плюсах...вместо массивов std::vector

В чём проблема использовать массивы в плюсах?

mbivanyuk ★★★★★
()
Ответ на: комментарий от mbivanyuk

Где проблема? Нед проблем, хочешь - юзай.

FIL ★★★★
()

Даже с задачками для первого класса не справляешься?

sed -i 's,i=primes\[found_primes\],primes\[found_primes\]=i,;s,i%primes\[j\],i%primes\[j\] == 0,' govnokod.cpp
kim-roader ★★
()
Ответ на: комментарий от mbivanyuk

В чём проблема использовать массивы в плюсах?

~ можно легко уехать за границы стека, можно сделать слишком большой размер массива и снова уехать за его границы. Больше нелокализованных данных и кода (~ массив и кол-во заюзанных в нём элементов одна сущность). Всё это актуально для неаккуратных кодеров, ~ сначала нужно научиться кодить, а потом пытаться юзать массивы.

mashina ★★★★★
()
Ответ на: комментарий от mashina

ну ТС же царя просит внести, а ты ему про эти самые „легко выйти за границы массива“. В сплюсе и без этого можно дров наломать.

nanoolinux ★★★★
()
Ответ на: комментарий от mashina

можно легко уехать за границы стека, можно сделать слишком большой размер массива и снова уехать за его границы

Да, но если никуда не уезжать а писать грамотно то код получится быстрым и компактным. Нет?

mbivanyuk ★★★★★
()

В двухтомнике Страуструпа эти все вещи должны разжевываться.

Выходить по goto заманичво, но не гарантирует освобождение ресурсов.

Как говорится: как вошел, так и выходи в обртаном порядке...

anonymous
()

всю жизнь пользуюсь break. брат жив. и какие аргументы для break вы используете в вашем пыхе?

bvn13 ★★★★★
()

в «этих самых наших плюсах» - вложенный цикл это потенциальное место для рефактора, то есть чего-то нехватает - класса/шаблона/итератора и так далее. Поэтому к циклам и выходам из них надо относится соответсвенно - goto/break/continue по возможности разумно избегать. (это конечно безотносительно к приведённому полоумному примеру :-) )

MKuznetsov ★★★★★
()
Ответ на: комментарий от mbivanyuk

в том, что если уж у тебя есть vector то лучше использовать vector.

Dark_SavanT ★★★★★
()

логично что такие говн$кодеры как ты обожают systemd ибо подобное тянется к подобному

anonymous
()
Ответ на: комментарий от mbivanyuk

Да, но если никуда не уезжать а писать грамотно то код получится быстрым и компактным. Нет?

Это сильно зависит от юз. кейса. Например, в случае кода ТС с массивами он не будет быстрее, менее компактен и не получится в общем случае не уехать за границы.

mashina ★★★★★
()
Ответ на: комментарий от mix_mix

Мдя, я банально переменную и присваиваемое в 21-й строке перепутал. Ну хоть в лужу громко пёрнул. Жалко, Царь не пришёл и не сказал, какой я чудак и с какой буквы.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от mashina

Почитал про этот ваш find_if — оверхедненько как-то, да и не для того предназначен изначально. А пихать во все поля vector — это вообще ООП головного мозга.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

Почитал про этот ваш find_if — оверхедненько как-то

В каком месте? Это ровно то, что делаешь вторым циклом.

А пихать во все поля vector — это вообще ООП головного мозга.

Это не все поля, а конкретное место в твоём коде.И это не «ООП головного мозга», а способ помочь людям вроде тебя меньше косячить.

mashina ★★★★★
()
Ответ на: комментарий от bvn13

Можно задать цифрой глубину выхода. А в JS вообще метки для break/continue есть (хотя там как раз это костыльная замена goto).

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от anonymous

обожают

Поставил => осилил => не снёс теперь «обожает» называется? okay

MiniRoboDancer ★☆
() автор топика

После вложенного цикла проверять в основном как он вышел. Например, для for можно сравнить переменную цикла с конечным значением, для while проверить условие, в крайнем случае завести переменную-флаг. Если становится ясно, что цикл прервался не естественным путём, то делать break

KivApple ★★★★★
()
Ответ на: комментарий от mashina

Это ровно то, что делаешь вторым циклом

Там как минимум лишнюю функцию объявлять нужно. Операций больше выходит в итоге.

а способ помочь людям вроде тебя меньше косячить

Лишние абстракции в случае непонимания их работы только усугубляют ошибки.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от KennyMinigun

Какие у вас симпатичные кеды, однако. Респект!

EXL ★★★★★
()
Ответ на: комментарий от MiniRoboDancer

Там как минимум лишнюю функцию объявлять нужно.

Не нужно, есть лямбды.

Операций больше выходит в итоге.

Это с объявлением ф-ии вообще никак не связано.

Лишние абстракции в случае непонимания их работы только усугубляют ошибки.

Просто законченный php головного мозга. Абстракция типа вектор в твоём коде и так есть независимо от твоего желания и признания её наличия. Вопрос только как с ней будешь работать - на коленке гогнокодить из трёх переменных {MAX_SIZE, found_primes, primes} или юзать готовую реализацию в виде всего одного объекта с простым интерфейсом. В случае наколеночного гогнокода гораздо проще чего-то потерять.

mashina ★★★★★
()

до кучи замечу, что проверять число n на делимость надо не по всему массиву primes, а только до простых чисел, которые [latex]\leq \sqrt n[/latex].

Ну и есессно четные можно сразу пропускать. То есть делай не i++, а i+=2.

dikiy ★★☆☆☆
()
Последнее исправление: dikiy (всего исправлений: 3)
Ответ на: комментарий от mashina

Не нужно, есть лямбды

Я ж не сказал, что её нужно пихать с именем и в общую область видимости.

Это с объявлением ф-ии вообще никак не связано

Связано, ибо без неё можно обойтись.

в виде всего одного объекта с простым интерфейсом

А если в объекте чего лишнего есть?

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от dikiy

Я уже исправил код до рабочего состояния и оптимизировал до более чем приемлемой скорости. Смысла проверять через одно не вижу — придётся городить для первого случая, а чётные и так отметаются на первой же итерации, особого оверхеда от них нет.

MiniRoboDancer ★☆
() автор топика
Ответ на: комментарий от MiniRoboDancer

Значит что-то не так сделал. Например, не сделал preallocate вектора.

mashina ★★★★★
()
Ответ на: комментарий от MiniRoboDancer

Если считаешь каждую пару байтов, то писать надо сразу на С.

NegatiV
()

Кстати, на старом OpenBSD в многопоточном приложении вот такое будет падать

        #define MAX_SIZE 100000
        long primes[MAX_SIZE];

Причем с невнятной диагностикой. Там очень маленький размер pthread-стека по умолчанию. И наверняка есть еще такие чудные платформы. Если планируешь широко распространять свой софт, лучше на стеке много не выделять

anonymous
()

Break есть но вообще break/continue - это Дейкстра не одобряет.

cattail
()
Ответ на: комментарий от SilverPro

А ещё нельзя флешки без отмонтирования дёргать и несертифицированные браузеры ставить, ага.

MiniRoboDancer ★☆
() автор топика

деления на ноль ТОЧНО нет, без goto отрабатывает нормально.

Может быть без goto gcc просто выбрасывает деление, как бессмысленное?

Legioner ★★★★★
()

А вообще кошерный выход из вложенных циклов это заворачивание этих циклов в функцию и return в нужном месте. Вот и всё.

Legioner ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.