metaclass: (Default)
metaclass ([personal profile] metaclass) wrote2012-04-21 09:12 pm

Чистый C, обработка ошибок

Это, а как в C принято обрабатывать ошибки?
Т.е. обычная программа: я открываю всякие ком-порты, сокеты и файлы, что-то с ними пытаюсь делать, затем закрываю. В дельфи/java/C#/Clojure это всегда делается через обработку исключений в виде try-finally/using или чего-то аналогичного, в C++ - RAII, а вот что делать в С? Аналогично, с выводом сообщений об ошибке - try{..}catch(Exception e) {logger.Fatal(e};raise}

Я каждую вызываемую функцию проверяю на адекватность возвращаемого результата и при ошибке вывожу в stderr сообщение и strerror(errno), причем выглядит это достаточно единообразно, чтобы хотелось автоматизировать, но принято ли делать хитрожопые макросы типа CHECKERROR(some_call(),"some_call failed") и из них вываливаться из программы при ошибках?

А, и это - принято ли в C заниматься конкатенацией строк по поводу и без повода? А то, скажем, я привык в простых программах особо не мудрить и при необходимости складывать строки, если нет явных требований к производительности. Например, какая-нибудь дурь типа генерации строковых команд из шаблонов и параметров - тупо поскладывал строки и вернул результат. А в С придется strcat использовать, буфера какие-то объявлять, память выделять, трястись за ее удаление или же писать результат прямо в выходной файл, что вообще tight coupling.
(deleted comment)

[identity profile] sbj-ss.livejournal.com 2012-04-21 08:21 pm (UTC)(link)
Ребе, есть одна проблема. Помните, почему во времена царя Ирода Бейсика было хорошим тоном нумеровать команды с шагом в 10? :)
Тут то же самое. Если при доработке кода между вызовами func1 и func2 потребуется делать вызов func3, то придётся либо делать stage вещественным числом (и до 1.0625 запросто дойдёт), либо запутывать себе голову.
Код такой имеет определённое право на жизнь, да, но хотя бы enum для stage объявить не мешает.
Edited 2012-04-21 20:28 (UTC)
(deleted comment)

[identity profile] sbj-ss.livejournal.com 2012-04-21 08:39 pm (UTC)(link)
А stage при этом присваивается 47? :)
Иногда ж ресурсы приходится освобождать в порядке, обратном выделению.
(deleted comment)
(deleted comment)

[identity profile] sbj-ss.livejournal.com 2012-04-21 09:45 pm (UTC)(link)
Чем определяется размер стека? :)

[identity profile] sbj-ss.livejournal.com 2012-04-21 09:33 pm (UTC)(link)
В реальной жизни захват и освобождение ресурсов не нумерованы. Т.е. будет acquireSomeRes(), allocSomeRes(), getSomeRes(), InitSomeRes() и парные им freeSomeRes(), releaseSomeRes(), deAllocSomeRes(), weDontNeedThisResAnyMore() - и, по закону подлости, именно в парном соответствии. А константа состояния захвата 47 не говорит ничего.
Почему я и настаиваю на использовании для stage перечисления вида
typedef enum _someOpStage {
SOME_OP_STAGE_Res1,
SOME_OP_STAGE_Res2,
/* ... */
} someOpStage
Edited 2012-04-21 21:37 (UTC)