2013-04-06 1 views
22

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

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

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

int bar() 
{ 
    try 
    { 
     foo(); 
    } catch (exception e) { return 1; } 
} 
+0

[Родственный вопрос] (http://stackoverflow.com/questions/4695741/is-there-a-gcc-option-to-assume-all-extern-c-functions-cannot-propagate-except). –

+1

Ответы утверждают, что вы вызываете неопределенное поведение, если исключение выбрано из кода C++ в фактический код C (который не знал, что делать с исключением). Я думаю, что это правильно, но вы спрашиваете о вызове 'extern 'C' 'функций из C++ или C?Если вы вызываете их из C++ (и никогда не с C), возникает неизбежный вопрос: «Почему функции« extern »C« если они никогда не вызываются с другого языка? », Но я думаю, что просто вызов функций C++ с 'extern 'C" из C++ означает, что границы языка не пересекаются и, следовательно, не определено неопределенное поведение. –

+0

Спасибо всем, кто внес свой вклад в ответ на это. Если я правильно понял, окончательный ответ на мой вопрос заключался в следующем: extern «C» не меняет способ обработки исключения. Однако бросание исключения, которое не поймано и пересекает границы языка, имеет неопределенное поведение. –

ответ

8

«Могут ли функции C++ отмечены как« Extern »C« throw »?

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

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

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

Таким образом, нижняя линия: НЕ исключение из функции, обозначенной как extern "C".

+0

Это может быть технически «неуказанное поведение», но в любом случае: не хорошо. –

+0

Действительно ли стандарт C++ говорит, что это неопределенное поведение, когда исключение пересекает границы языка? Мне трудно полагать, что, поскольку стандарт C++ имеет дело только с C++ и C++, а «языковые границы» выходит за рамки C++. Я бы предположил, что если исключение C++ выбрано на язык, который не поддерживает исключения C++, исключение распространяется только до тех пор, пока оно не будет найдено где-то или программа не будет завершена. Но, конечно, это зависит от операционной системы и компилятора. – user1610015

+2

Вы не можете сказать 'YES', когда его' undefined behavior'. Когда вы вызываете 'undefined behavior', ваш код в основном прерывается. –

0

Вот ответ на ваш вопрос: http://yosefk.com/c++fqa/mixing.html#fqa-32.6

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

+15

«Скомпилируйте его и попробуйте» никогда не бывает хорошей идеей для языков с неопределенным поведением. –

+4

Но это может привести к ошибочным предположениям о поведении кода, поскольку на самом деле вы не должны предполагать что-либо вообще, потому что оно не определено, и компилятор может что-то с ним делать. –

+5

@PiotrJaszkowski: Он не может уничтожить вселенную, но драконы вытолкнут ваш нос. Попытка «неопределенного поведения» бессмысленна, вы ничего не узнаете, поскольку тест не имеет смысла. –

2

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

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

компилирует хорошо

4

Для GCC the answer seems inconclusive.

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

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

Так визуальный_режим C++ это зависит от параметров компилятора получить ли вы определили поведение ,

+1

+1, но вы пропустили ответ gcc в одном из связанных комментариев: '-fexceptions'. Из gcc docs: «... вам может понадобиться включить этот параметр при компиляции кода C, который должен правильно взаимодействовать с обработчиками исключений, написанными на C++». – EML

 Смежные вопросы

  • Нет связанных вопросов^_^