LINUX.ORG.RU

Литература, пример проекта обработки ошибок на С

 


0

3

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

В любой крупный проект гляди. Kernel например.

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

В языках, отличных от сишки, есть bound-checking. Это лучше любых тестов.

Только работать это будет медленней, особоенно если заниматься перемножением матриц или чем-то похожим

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

Вам шашечки или ехать?

Это сразу решает целый класс проблем.

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

Ну а документация и тесты на плюсах - вообще боль, по сравнению с растом,
на плюсах всё еще в 3-е раза быстрее версии на расте

раст подходит лучше

Вам таки шашечки, или ехать?

shkolnick-kun ★★★★★
()

http://wiki.tuhs.org/doku.php?id=start

посёрфи там есть сишные(и чутка шеловые)сырцы - по технологическим причинам лаконичные и понятные.

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

Обработка ошибок опущена (для краткости, разумеется).

Ты как тот туповатый аноним тоже читать не умеешь? Я использую исключения. Если лично тебе нужно возвращать значения, велкам - возвращай прокси и обмазывайся проверками.

В общем, ждать было нечего.

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

slovazap ★★★★★
()
Ответ на: комментарий от shkolnick-kun

Я готов пожертвовать небольшим количеством производительности ради удобства.

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

надо запомнить приёмчик спасибо

как такое называется по-научному

rogerw
()
Ответ на: комментарий от SZT

Работа с массивом (или там std::vector) с проверкой границ на каждый чих - она попросту неэффективна

Ещё один с шаблонным мышлением. Ты считал какой одна инструкция будет давать реальный оверхед? Посчитай. Ты представляешь в каком жалком проценте случаев он будет боттлнеком? Прикинь. А потом добавь перед этими боттлнеками проверки диапазона и дай там самым компилятору возможность оптимизировать даже это одно сравнение в ноль (да, это и есть Array Bounds Check Elimination из жавы, у нас она скромно называется обычной оптимизацией и работает на всём).

Пилите тогда уже какой-нибудь верификатор

Обёртки над типами с compile-time проверкой диапазона реализуются тривиально. Наверняка уже есть, я не искал.

В общем, ещё раз: в C++ для безопасного программирования открыты все двери, а в plain C у вас нет и никогда не будет вариантов помимо простыни нечитабельного говнокода с ручными проверками, половина из которых забыта.

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

Я уже написал несколько раз: что с исключениями, что с возвращенем значения (что конкретно использовать решать разработчику в конкретном случае) на C++ для этого примера всегда получается код из одной строки

Ну-ка, где ты там написал код с возвращением ошибки в одну строку, показывай.

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

Ещё один с шаблонным мышлением. Ты считал какой одна инструкция будет давать реальный оверхед? Посчитай. Ты представляешь в каком жалком проценте случаев он будет боттлнеком? Прикинь.

Ну вообще-то это тебе надо считать и прикидывать, ведь это ж ты выступаешь за введение этих проверок. И что ты предлагаешь прикидывать? На каком коде? Если инструкция будет вызываться в цикле, то этих мусорных инструкций наберется очень много, и оверхед будет значительным.

Обёртки над типами с compile-time проверкой диапазона реализуются тривиально. Наверняка уже есть, я не искал.

А теперь сходи по ссылке http://www.ssw.uni-linz.ac.at/Research/Papers/Wuerthinger07/Wuerthinger07.pdf и хотя бы бегло проанализируй то, что там написано. Кстати по этой же статье можно и прикинуть, какой там будет оверхед. См. Figure 9: Speedup when using the bounds check elimination algorithm

На некоторых задачах наличие проверок замедляет работу в два раза.

В общем, ещё раз: в C++ для безопасного программирования открыты все двери

Почему в эти двери никто не входит? Почему с завидной регулярностью обнаруживаются ошибки при работе с памятью в плюсовом коде, например в том же вебките? По-твоему там дураки сидят? Давай, расскажи им как надо

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от slovazap

а в plain C у вас нет и никогда не будет вариантов помимо простыни нечитабельного говнокода с ручными проверками

Как насчет

#define MY_CHK_ARR(prefix,a,i,postfix) \
do{                                    \
    if (MY_UNLIKELY(i > MY_SZ_(a))) {  \
        printf("Out of bounds access: %s: %d", __FILE__, __LINE__); \
        exit(-1);                      \
    }                                  \
    prefix a[i] postfix;               \
}while (0)

По сути - та же 1 иснстукция.

Без простыни.

shkolnick-kun ★★★★★
()
Последнее исправление: shkolnick-kun (всего исправлений: 3)
Ответ на: комментарий от SZT

Ну вообще-то это тебе надо считать и прикидывать, ведь это ж ты выступаешь за введение этих проверок. И что ты предлагаешь прикидывать? На каком коде?

На своём. Заметишь оверхед - поговорим.

А теперь сходи по ссылке

Я Ъ, и JAVA меня не интересует от слова никак. Ты хочешь казаться крутым анализатором - расскажи своими словами, а не ссылками кидайся.

Почему в эти двери никто не входит? Почему с завидной регулярностью обнаруживаются ошибки при работе с памятью в плюсовом коде, например в том же вебките? По-твоему там дураки сидят?

Сам-то как думаешь? Может ты считаешь что там по определению боги? Ты PDF'ку-то сам читал? Все проблемы только из-за сишных техник.

slovazap ★★★★★
()
Последнее исправление: slovazap (всего исправлений: 1)
Ответ на: комментарий от slovazap

На своём. Заметишь оверхед - поговорим.

Только вот на плюсах я вообще не пишу, так что увы. Думаю что Speedup when using the bounds check elimination algorithm из той pdf которую ты читать не хочешь - уже достаточно показывает, какой там оверхед. А написать синтетический пример, где оверхед будет очень большой или наоборот очень маленький - это вообще тривиально, и смысла так делать нет никакого.

Я Ъ, и JAVA меня не интересует от слова никак. Ты хочешь казаться крутым анализатором - расскажи своими словами, а не ссылками кидайся.

Своими словами там так просто не описать, там есть всякие блок-схемы, loop-invariant checks, в общем эти твои «Обёртки над типами с compile-time проверкой диапазона» о которых ты писал - это вообще полная фигня по сравнению с этим (и то оно устраняет далеко не все бесполезные проверки границ). А если использовать нечто вроде Frama-C и добавить контрактов, доказав их через SMT-солверы и систему доказательства теорем Coq, то вообще от проверки границ можно избавиться для любых случаев(Xотя есть всякие undecidable проблемы, где так уже не сделать, увы. Но вряд ли с ними можно столкнуться в реальной жизни (не на синтетических примерах) в контексте проверки границ массива и прочей работы с указателями).

Сам-то как думаешь? Может ты считаешь что там по определению боги?

Я вообще-то у тебя спрашиваю, что ты по этому поводу думаешь. Нечего тут стрелки переводить. Если такой умный - смело иди работай над Webkit за деньги, реализуй там свою инновационную методику избавления от багов, уверен что тебе много денег заплатят за такое. Только я сильно сомневаюсь, что ты в плюсах лучше шаришь чем те, кто пишут этот самый Webkit.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 5)
Ответ на: комментарий от SZT

Только вот на плюсах я вообще не пишу, так что увы.

Но свои 5 копеек всегда вставишь.

Своими словами там так просто не описать, там есть всякие блок-схемы, loop-invariant checks, в общем эти твои «Обёртки над типами с compile-time проверкой диапазона» о которых ты писал - это вообще полная фигня по сравнению с этим (и то оно устраняет далеко не все бесполезные проверки границ).

«Я ничего не понял, но ты дурак».

А если использовать нечто вроде Frama-C

Да, deep blue ещё подключи. Ради устранения сферического оверхеда в вакууме который ты даже посчитать не можешь.

Только я сильно сомневаюсь, что ты в плюсах лучше шаришь чем те, кто пишут этот самый Webkit.

«Написали дырявое дерьмо, но шарят точно лучше тебя».

Если такой умный - смело иди работай над Webkit за деньги

Это вообще апофеоз. Ты просто бог логики.

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

Да, deep blue ещё подключи. Ради устранения сферического оверхеда в вакууме который ты даже посчитать не можешь.

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

«Написали дырявое дерьмо, но шарят точно лучше тебя».

Ну вот пойди и напиши лучше

Это вообще апофеоз. Ты просто бог логики.

В общем ясно все. Разговор окончен

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

Обработка ошибок опущена (для краткости, разумеется).

Ты как тот туповатый аноним тоже читать не умеешь? Я использую исключения.

И где там запуск исключения? Писать ты вроде умеешь.

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

Я ждал нормального чейнинга, в котором можно вызывать разные методы с разной сигнатурой. То, что показал ты, на практике бесполезно.

tailgunner ★★★★★
()
Ответ на: комментарий от shkolnick-kun

По сути - та же 1 иснстукция.

По сути, это ручная проверка, которую можно забыть. И кстати, что делать, если проверка не прошла? Валить программу - не вариант.

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

Почему с завидной регулярностью обнаруживаются ошибки при работе с памятью в плюсовом коде, например в том же вебките?

Ты всегда можешь сравнить частоту ошибок в Webkit с любым современным браузером на Си. А, нет... не можешь.

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

Ты всегда можешь сравнить частоту ошибок в Webkit с любым современным браузером на Си. А, нет... не можешь.

А я нигде и не утверждал, что при использовании Си будет меньше ошибок с памятью, чем с плюсами. В плюсах-то их будет как раз меньше, если грамотно писать код. Но пихать всюду проверки границ в плюсах чтобы обезопасить код от подобных ошибок это как минимум глупо, проще уж свалить на ту же Java где они сами автоматом встраиваются, и даже иногда убираются встроенным оптимизатором HotSpot (так что в итоге это может даже быть быстрее).

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

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

И что же означали твои слова:

SZT> Почему с завидной регулярностью обнаруживаются ошибки при работе с памятью в плюсовом коде, например в том же вебките? По-твоему там дураки сидят?

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

И что же означали твои слова:

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

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

А, тебе просто нравится говорить банальности...

Ну, выше по треду были личности, которые эти банальности походу не понимают. Например тут
Литература, пример проекта обработки ошибок на С (комментарий) :

и ошибиться становится невозможно

Литература, пример проекта обработки ошибок на С (комментарий) :

но они легко ловятся valgrind-ом и ты их УСПЕШНО фиксишь в минимальный срок

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

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

Когда человек говорит что сделать нечто невозможно он имеет ввиду обычно то, что этого или нельзя сделать вообще, или сделать можно, но это настолько трудно, что можно считать что так сделать вообще нельзя. Например, «Невозможно слепоглухому человеку попасть из рогатки c десяти метров в воробья» - с этим утверждением вполне можно согласиться, но тем не менее существует очень мизерная вероятность такого попадания. А вот утверждение «Невозможно решить проблему останова» - справедливо на все 100%.

Когда же кто-то утверждает, что используя плюсы ошибиться становится невозможно - это явный бред.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

Когда же кто-то утверждает, что используя плюсы ошибиться становится невозможно - это явный бред.

Значит, ты всё же понял фразу как «ошибиться становится невозможно вообще». Это о многом говорит.

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

Нет, фразу эту я понял как «ошибиться становится практически невозможно» (как в том примере со слепоглухим, который я приводил) но данный смысл этой фразы - тоже полный бред.

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

раньше ты не опускался

Поплачь обо мне, пока я живой.

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

Написать функцию my_cool_new для выделения памяти, служебную функцию _my_cool_free_em_all для освобождения и макрос обертку для пользовательского кода по типу:

#define MY_COOL_FUNC(type, func,...) \
type func##payload(__VA_ARGS__);     \
type func(__VA_ARGS__)               \
{                                    \
   type ret;                         \
   ret = MY_COOL_JMP(func##payload); \
   _my_cool_free_em_all();           \
   return ret;                       \
}                                    \
type func##payload(__VA_ARGS__)

Придется делать костыльна асме, если без него, то тогда просто макросы

#define MY_COOL_ENTER() _my_cool_alloc_stack_init()
#define MY_COOL_RETURN _my_cool_free_em_all();return

Но его наличие придется проверять ручками или статическим анализвтором.

shkolnick-kun ★★★★★
()
Последнее исправление: shkolnick-kun (всего исправлений: 3)
Ответ на: комментарий от SZT

bound-checking в некоторых (ржавых) языках отключается в релиз-билде, соотвественно все грабли при отладке поймаются
Нет никакой проблемы сделать то же самое условной компиляцией в C или C++

mersinvald ★★★★★
()
Последнее исправление: mersinvald (всего исправлений: 1)
Ответ на: комментарий от mersinvald

Связанные с выходом за границы — поймаются.

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

eao197 ★★★★★
()
Ответ на: комментарий от zudwa
do {
    if( (result=do1()) ) break;
    if( (result=do2()) ) break;
} while (0);

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

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

И где там запуск исключения? Писать ты вроде умеешь.

Что такое «запуск исключения»? throw - в Send(), catch - там где тебе нужно его обработать. Детский сад.

Я ждал нормального чейнинга, в котором можно вызывать разные методы с разной сигнатурой.

А в чём проблема? I2C().Send(foo).Recv(bar)

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

Детский сад.

Один ты тут взрослый мужчина. И нетупой, да.

А в чём проблема? I2C().Send(foo).Recv(bar)

В том, что твой вариадик и этого не умеет. А вызывать методы с разным количеством аргументов он не умеет совсем.

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

Не отменяет. Но, как показывает жизнь, тесты не способы выловить все ошибки. Поэтому тезис о том, что debug-сборка при отладке выловит обращения по неправильным индексам, просто-напросто несостоятелен. Какую-то часть выловит, но не более.

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

В том, что твой вариадик и этого не умеет.

Глупенький. Он не может и не должен этого уметь. Он сахар для посылки нескольких сообщений пачкой, который сокращает код и делает его читабельнее [ещё более]. Не знаю чего ты себе навоображал и зачем.

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

Глупенький.

До тебя мне далеко.

Он не может и не должен этого уметь.

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

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

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

Продемонстрировал ровно и только то что ты просил.

И да, кстати, на самом деле Send(header, data) без оверхеда, потому что variadic template.

Что, вот совсем без оверхеда? Покажи, как.

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

А какая разница на чем упадет релиз: на выходе за пределы или на последствиях?
Тем более что если тебе не важна незначительная просадка на проверках — ты можешь ее не вырубать.

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

Ну тут уж выбирать что важнее: гарантия сохранности данных или бОльшая производительность, требующая более тщательных тестов.

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

А какая разница на чем упадет релиз: на выходе за пределы или на последствиях?

Разница просто офигенная: либо падаешь сразу в месте проблемы, либо портишь данные и это вылазит боком хрен знает где.

Тем более что если тебе не важна незначительная просадка на проверках — ты можешь ее не вырубать.

Кто сказал, что не важна. И размер просадки будет сильно зависеть от выполняемой операции: одно дело, когда нужно у двух-трех строчек лидирующие и финальные проблемы выкусить, совсем другое дело — перемножение/обращение больших матриц.

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