Здравствуйте, Lonely Dog, Вы писали:
LD>Я 15 лет пишу на C++, немного знаю C#, Python и пр. Но совершенно не понимаю, как писать на C. Как организовывать обработку ошибок (исключений нет, значит остаются коды возврата или setjmp/longjmp). RAII нет, значит надо в конце функции все чистить самому.
Ну да, так и пишем, все руками. Полезность C++'ных автоматизмов сильно переоценена. В том смысле, что необходимость делать все явно добавляет, конечно, работы, но не так, чтобы очень много. С другой стороны, Си не подбросит сюрприза от того, что что-то автоматически случилось, с неочевидными побочными эффектами, а где и что, поди пойми.
Обработка ошибок в виде явно возвращаемых кодов возврата — это не такой уж и плохой вариант. В отличии от исключений, все перед глазами и все легко читается, ошибка не прилетит неизвестно откуда и не улетит неизвестно куда. setjmp/longjmp для обработки ошибок очень мало подходят, это экзотические функции, которые бывают полезны в редких случаях.
LD>Знаю, что у MS в драйверах используется goto cleanup для этих целей. Что-то типа:
Да, это стандартный паттерн, когда надо сделать длинную последовательность действий (сложная инициализация, конструирование сложного объекта и т.п.) и хочется иметь централизованную обработку ошибок на случай, если что-то пошло не так. Достоинством такого подхода является то, что саму сложную последовательность можно редактировать, не боясь сломать обработку ошибок.
LD>Понятно, что можно использовать alloca для автоосвобождения памяти. Но не везде это подходит (стек все-таки ограничен).
alloca освобождает память, но не закрывает файлы и т.п. Кроме того, с указателями, полученными от alloca, надо быть осторожным. Они становятся невалидными при выходе из функции, и могут стать невалидными при выходе из блока (я на такое нарывался, наверное, это был глюк компилятора, но кому от этого легче?).