C++ Standard заявляет следующее о выполнении std::call_once
с функциями, которые бросают исключение (§30.4.4.2/2):Бросив исключение из станда :: call_once
2/Эффекты: выполнение call_once который не вызывает его func, является пассивным исполнением. Выполнение call_once, вызывающего его func, является активным исполнением. Активное выполнение должно вызвать INVOKE (DECAY_- COPY (std :: forward (func)), DECAY_COPY (std :: forward (args)) ...). Если такой вызов функции func вызывает исключение, выполнение является исключительным, в противном случае оно возвращается. Исключительное исполнение должно распространять исключение на вызывающего абонента call_once. Среди всех исполнений call_once для любого заданного значения once_flag: самое большее должно быть возвратное исполнение; если есть возвращаемое исполнение, это будет последнее активное выполнение; и существуют пассивные казни только в случае выполнения возвращаемого исполнения. [Примечание: пассивное выполнение позволяет другим потокам надежно наблюдать результаты, полученные в результате более раннего возвращения. - конец примечание]
Я использую Visual Studio 2012 и работаю следующий код:
void f(){
throw std::exception("Catch me!");
}
int main(int argc, char* argv[]){
once_flag flag;
try{
call_once(flag, f);
} catch(const std::exception& e){
cout << e.what() << endl;
}
return 0;
}
Мой результат: код в прогонах поймать блок и выводит сообщение, но когда программа существую я получаю вызов abort()
и следующее сообщение, выводимое COUT:
... \ mutex.c (38) мьютекса разрушен во время занят
Это должно произойти?
Нет, это ошибка, программа должна работать нормально (хотя вы используете нестандартный конструктор для 'std :: exception', в ISO C++ вы можете использовать только конструкцию по умолчанию' std :: exception', что вызывает частые проблемы с переносимостью, когда пользователи MSVC проверяют incode, предназначенные для компиляции в других реализациях) –