Исключения в языке C

Пишу небольшую программу на C. Работаю в Code::Blocks. Искал, как можно обрабатывать исключения в языке C, нашёл описание __try __except на docs.microsoft.com, но компилятор почему-то на него ругается. Подскажите, как я могу сделать обработку исключений.


Ответы (1 шт):

Автор решения: AlexGlebe

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

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

Возвращение в нужный участок программы и продолжение выполнения в месте, где находится точка фиксация реализована с помощью функции setjmp. Она ловит исключение или фиксирует начальную точку.

Запуск исключения производиться с помощью функции longjmp.

Она может создать только исключение типа int и если программист хочет работать с другим типом, то опять он должен всё это написать сам. Например исключение номер 3 будет означать, что само исключение хранится в структуре номер три.

Вот пример плюсовой, и аналог в Си:

C++

// g++ -std=c++11 mainpp.cpp -o mainpp
# include <iostream>

void fun(void) {
  std::cout << u8"fun:начало..."<<std::endl;
  throw 666 ; }
  
int main  ( ) {
  try {
    fun ( ) ; }
  catch(int e) {
    std::cerr<<u8"Ошибка номер "<<e<<std::endl;
    return e ; }
  catch ( ... ) {
    throw ; } }

C

// gcc -std=c11 main.c -o main
# include <stdio.h>
# include <setjmp.h>

// у каждой нити исключения движутся своим
// путём, по-этому у них отдельные указатели
_Thread_local jmp_buf * gloval_jbp ;

void fun  ( void  ) {
  printf ( u8"fun:начало...\n"  ) ;
  longjmp ( * gloval_jbp , 666 ) ; }

int main  ( ) {
  jmp_buf jb  ;
  jmp_buf * const jbold = gloval_jbp  ;
  // начала области захвата исключений
  gloval_jbp  = & jb  ;
  int exc ;
  switch  ( ( exc = setjmp  ( jb  ) ) ) {
  case  0 :
    fun ( ) ;
    // конец области захвата исключений
    gloval_jbp  = jbold ;
    break ;
  case  666 :
    // конец области захвата исключений
    gloval_jbp  = jbold ;
    printf ( u8"main:поймали исключение №666\n"  ) ;
    return  666 ;
  default :
    // нераспознанный номер исключения
    // конец области захвата исключений
    gloval_jbp  = jbold ;
    // пускаем обработку исключения дальше
    // аналог throw ;
    longjmp ( * gloval_jbp , exc ) ; } }
→ Ссылка