Выброс C++ исключение через вызов функции C
У меня есть три свободные функции: F0, F1 и F2. F0 вызывает F1, который, в свою очередь, вызывает F2.
F0 и F2 являются C++ функциями, где F1 является функцией C. F2 подвергается воздействию F1 через: extern "C"
Код для каждой из свободных функций выглядит следующим образом:
~~~~ F0.cpp ~~~~
void f0()
{
try
{
f1();
}
catch (...)
{}
}
~~~~ F0.cpp ~~~~
~~~~ F1.c ~~~~
void f1()
{
f2();
}
~~~~ F1.c ~~~~
~~~~ F2.cpp ~~~~
void f2()
{
throw 1
}
~~~~ F2.cpp ~~~~
Вопрос:
Исправлено ли в f2 исключение, прошедшее через f1 и правильно пойманное в f0?
Или std :: неожиданно вызывается из-за того, что исключение не обрабатывается, или все это должно быть неопределенным поведением? - если это так, где в стандарте говорится об обработке исключений в этом конкретном контексте.
Обратите внимание, что речь идет не об обработке исключений в C, а о том, что происходит в ситуации, когда исключение может протекать через уровень C (если вообще) и быть пойманным на вызывающем C++ уровне - и любые возникающие побочные эффекты и т.д.
Ответы
Ответ 1
Это специфичный для платформы и специфический для компилятора вопрос.
Например, в Linux/GCC вам необходимо скомпилировать C-код с -fexceptions
, после чего разматывать таблицы будут сборки, а исключение - с помощью кода C.
Из https://gcc.gnu.org/onlinedocs/gcc-7.3.0/gcc/Code-Gen-Options.html#index-fexceptions
-fexceptions
Включить обработку исключений. Создает дополнительный код, необходимый для распространения исключений. Для некоторых целей это означает, что GCC генерирует информацию о распаковке кадра для всех функций, что может привести к значительным накладным расходам данных, хотя это не влияет на выполнение. Если вы не укажете этот параметр, GCC позволяет по умолчанию использовать такие языки, как C++, которые обычно требуют обработки исключений, и отключает его для таких языков, как C, которые обычно не требуют этого. Однако вам может понадобиться включить этот параметр при компиляции кода C, который должен правильно взаимодействовать с обработчиками исключений, написанными в C++. Вы также можете отключить этот параметр, если вы компилируете старые C++ программы, которые не используют обработку исключений.
Я менее знаком с разработкой Visual C++/Windows, но считаю, что обработка исключений будет использовать общие механизмы, если вы скомпилируете свой код C++ и C с параметром /EHa (разрешите смешивание структурированных и C++ исключений)
Ответ 2
Вы можете легко это сделать, вместо использования компилятора C
для компиляции вы можете использовать компилятор C++
.
#include <stdio.h>
#include <stdexcept>
void blablabla () {
throw std::runtime_error ("BLA BLA BLA");
}
int main ()
try {
blablabla();
} catch (std::runtime_error& e) {
printf("%s\n", e.what());
} catch (...) {
printf ("Unknown excetpion");
}
и выход:
BLA BLA BLA
Все, что мне нужно сделать, запускается после g++ myfile.c &&./a.out
и gcc myfile.c &&./a.out
. Этот шаг будет зависеть от вашего компьютера, компилятора и настройки.
Таким образом, вы можете поймать исключение C++
в своем C
коде, все, что вам нужно сделать, это скомпилировать его как C++. Если вы знаете, что что-то бросает исключение, вы можете просто поймать его в C
коде. Представьте, что если blablabla()
находится где-то в библиотеке, которую вы используете, вы можете просто написать:
int main (void) {
try {
blablabla ();
} catch (NameOfException& e) {
std::cout << e.what() << "\n";
}
}