Недавно на CodeReview.SE я наткнулся на ответ, в котором говорится о технике, называемой "исключение рвоты". По-видимому, этот трюк используется для использования того, что исключения должны быть реализованы поточно-безопасным образом независимо от того, поддерживает ли компилятор переменные thread_local
.
Вставьте часть этого ответа ниже:
Существует существующая методика, которая не является разнородной, называемой "исключающей рвотой". Обратите внимание:
void f(void(*p)()) { p(); } template<typename F> void real_f(F func) { try { throw func; } catch(...) { f([] { try { throw; } catch(F func) { func(); } }); } }
Это нарушает тот факт, что компилятор должен предоставить поток-локальный стек для сложных объектов для использования в качестве хранилища исключений, независимо от их поддержки других локальных функций потока, и, следовательно, пользуется широкой поддержкой компилятора. Наиболее очевидные недостатки: a) это ужасно, и b) он ограничен семантикой стека.
Мой вопрос в том, как этот трюк действительно работает и безопасен ли он?