Как бросить исключение в C?

Я набрал это в Google, но нашел только инструкции в C ++,

как это сделать на C?

73 голоса | спросил httpinterpret 23 Maypm10 2010, 16:48:30

10 ответов


0

Нет исключений в C. В C ошибки сообщаются по возвращенному значению функции, выходному значению процесса, сигналам процесса ( Сигналы программных ошибок (GNU libc) ) или аппаратное прерывание ЦП (или другая ошибка уведомления из ЦП, если есть ) ( Как процессор обрабатывает случай деления на ноль ).

Исключения определены в C ++ и других языках. Обработка исключений в C ++ определена в стандарте C ++ «Обработка исключений S.15», в стандарте C нет эквивалентного раздела.

ответил Brian R. Bondy 23 Maypm10 2010, 16:49:13
0

В C вы можете использовать комбинацию setjmp() и longjmp() функции, определенные в setjmp.h. Пример из Википедии

#include <stdio.h>
#include <setjmp.h>

static jmp_buf buf;

void second(void) {
    printf("second\n");         // prints
    longjmp(buf,1);             // jumps back to where setjmp 
                                //   was called - making setjmp now return 1
}

void first(void) {
    second();
    printf("first\n");          // does not print
}

int main() {   
    if ( ! setjmp(buf) ) {
        first();                // when executed, setjmp returns 0
    } else {                    // when longjmp jumps back, setjmp returns 1
        printf("main");         // prints
    }

    return 0;
}

Примечание: я бы действительно советовал вам не использовать их, поскольку они ужасно работают с C ++ (деструкторы локальных объектов не будут вызываться), и это действительно сложно чтобы понять, что происходит. Вместо этого верните какую-то ошибку.

ответил vava 23 Maypm10 2010, 17:36:30
0

Обычный старый C на самом деле не поддерживает исключения.

Вы можете использовать альтернативные стратегии обработки ошибок, такие как:

  • возврат кода ошибки
  • возвращает FALSE и использует last_error переменная или функция.

См. http://en.wikibooks.org/wiki/C_Programming/Error_handling .

ответил Lucas Jones 23 Maypm10 2010, 16:50:04
0

В C нет встроенного механизма исключения; вам нужно моделировать исключения и их семантику. Обычно это достигается с помощью setjmp и longjmp.

Вокруг довольно много библиотек, и я внедряю еще одну. Он называется exceptions4c ; это портативный и бесплатный. Вы можете взглянуть на него и сравнить его с другими альтернативами , чтобы узнать, какой из них подходит вам больше всего. /р>

ответил Guillermo Calvo 28 PMpThu, 28 Apr 2011 22:31:36 +040031Thursday 2011, 22:31:36
0

C может генерировать исключения C ++, они все равно являются машинными кодами. Например, в bar.c

// begin bar.c
#include <stdlib.h>
#include <stdint.h>
extern void *__cxa_allocate_exception(size_t thrown_size);
extern void __cxa_throw (void *thrown_exception, void* *tinfo, void (*dest) (void *) );
extern void * _ZTIl; // typeinfo of long
int bar1()
{
   int64_t * p = (int64_t*)__cxa_allocate_exception(8);
   *p = 1976;
   __cxa_throw(p,&_ZTIl,0);
  return 10;
}
// end bar.c

в a.cc,

#include <stdint.h>
#include <cstdio>
extern "C" int bar1();
void foo()
{
  try{
    bar1();
  }catch(int64_t x){
    printf("good %ld",x);
  }
}
int main(int argc, char *argv[])
{
  foo();
  return 0;
}

чтобы скомпилировать его

gcc -o bar.o -c bar.c && g++ a.cc bar.o && ./a.out

Выход

good 1976

http://mentorembedded.github.io/cxx-abi/abi- eh.html содержит более подробную информацию о __cxa_throw.

Я не уверен, является ли он переносным или нет, и я тестирую его с помощью 'gcc-4.8.2' в Linux.

ответил wcy 30 J0000006Europe/Moscow 2014, 14:41:00
0

C не имеет исключений.

Существуют различные хакерские реализации, которые пытаются это сделать (один пример по адресу: http://adomas.org/excc/).

ответил Joe 23 Maypm10 2010, 16:49:50
0

В Win MSVC есть __try ... __except ..., но это действительно ужасно, и вы не хотите его использовать если вы можете избежать этого. Лучше сказать, что нет никаких исключений.

ответил Donal Fellows 23 Maypm10 2010, 16:54:01
0

Этот вопрос очень старый, но я наткнулся на него и подумал, что поделюсь методом: делить на ноль или разыменовывать нулевой указатель.

Вопрос просто в том, «как бросить», а не в том, как поймать или даже как генерировать исключение определенного типа. У меня была ситуация давным-давно, когда нам нужно было вызвать исключение из C, чтобы быть пойманным в C ++. В частности, мы периодически получали сообщения об ошибках «чисто виртуального вызова функции», и нам нужно было убедить функцию _purecall среды выполнения C выдать что-то. Поэтому мы добавили нашу собственную функцию _purecall, которая делится на ноль, и boom, мы получили исключение, которое мы могли бы отловить на C ++, и даже использовать некоторое удовольствие от стека, чтобы увидеть, где что-то пошло не так.

ответил Joe 28 MarpmFri, 28 Mar 2014 18:00:19 +04002014-03-28T18:00:19+04:0006 2014, 18:00:19
0

Как упоминалось во многих потоках, «стандартный» способ сделать это - использовать setjmp /longjmp. Я опубликовал еще одно такое решение для https://github.com/psevon/exceptions- и-RAII-в-с Насколько мне известно, это единственное решение, основанное на автоматической очистке выделенных ресурсов. Он реализует уникальные и общие интеллектуальные указатели и позволяет промежуточным функциям пропускать исключения без перехвата и по-прежнему правильно очищать свои локально распределенные ресурсы.

ответил user3510229 8 PMpTue, 08 Apr 2014 20:21:41 +040021Tuesday 2014, 20:21:41
0

C не поддерживает исключения. Вы можете попробовать скомпилировать ваш код C как C ++ с помощью Visual Studio или G ++ и посмотреть, будет ли он компилироваться как есть. Большинство приложений C будут компилироваться как C ++ без существенных изменений, и тогда вы можете использовать синтаксис try ... catch.

ответил Mahmoud Al-Qudsi 23 Maypm10 2010, 16:50:24

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132