Могут ли функции C++, помеченные как Extern "C", бросать?


У меня есть функции C++, которые я хочу объявить с помощью extern "C", хотя они вызываются только в коде C++. Да, я знаю, что это странно, но это то, что я хотел бы сделать для согласованности, так как мы смешали объявления C и C++. Я просто хочу убедиться, что объявление функции C++ как extern "C" не повлияет на поведение метания.

Это выглядело бы примерно так:

extern "C" void foo() {throw exception;}

int bar()
{
    try
    {
        foo();
    } catch (exception e) { return 1; }
}
4 22

4 ответа:

"могут ли функции C++, помеченные как Extern "C", бросать?"

Да , в том смысле, что ни язык, ни компилятор не помешают вам сделать это.

Нет , в том смысле, что если вы бросите, это будет неопределенное поведение, так как исключение C++ пересекает границы языка.

На практике: не делайте этого. Поймать исключение и перевести его в код ошибки, или средство, которое другой язык может понять.

Итак, нижняя линия: do Не выбрасывать исключение из функций, помеченных как extern "C".

Для GCC ответ кажется неубедительным.

Документация MSVC , однако относительно ясна по этому вопросу:

  • /EHa и /EHs... указывает компилятору предположить, что функции, объявленные как extern "C", могут выдавать исключение.
  • /EHsc ... указывает компилятору предполагать, что функции, объявленные как extern "C", никогда не выбрасывают исключение C++

Таким образом, для Visual-C++ это зависит от параметров компилятора. вы получаете определенное поведение.

Он будет компилироваться, но это неопределенное поведение для броска из функции, помеченной как имеющая связь C. C не имеет исключений, поэтому в общем случае вы должны просто вернуть код ошибки и / или предоставить функцию, которая возвращает информацию о последней ошибке.

#include <exception>
extern "C" void foo() {throw std::exception();}

Хорошо компилируется

Здесь ответ на свой вопрос: http://yosefk.com/c++fqa/смешивания.сообщение: fqa-32.6

В принципе, вы не сможете поймать его. (но почему бы вам просто не скомпилировать его и не попробовать? :))