Спецификация C ++ может определять только те вещи, которые содержатся в спецификации C ++. Помните: спецификация C ++ определяет поведение виртуальной машины, которую она определяет. И если он не определяет, что что-то может случиться, он, конечно же, не определяет поведение C ++ в отношении того, что он не говорит, что может произойти.
Согласно спецификации C ++, поток может выйти ровно тремя способами: путем возврата из своей основной функции, выброса исключения через свою основную функцию и прямого выхода из процесса (как с std::terminate
или аналогичными функциями). Короче говоря, поток C ++ не может выйти другим способом. В стандартном C ++ нет функции ExitThread
. Точно так же std::thread
не может убить поток ни снаружи, ни внутри.
Следовательно, все, что действительно вызывает то, что, по словам C ++, не может произойти, по определению не определено. Я предполагаю, что это даже не было бы «неопределенным поведением»; это было бы в том туманном пространстве, в котором были потоки до того, как C ++ 11 фактически изложил, как работают взаимодействия потоков.
То же самое и с «сигналами», какими бы они ни были. В спецификации C ++ не сказано, что они могут вызвать завершение функции. Вот драконы.
Что касается longjmp
, это покрывается поведением longjmp
. Когда вы используете longjmp
для выхода из функции, эта функция никогда не завершается, как если бы вы использовали throw
и catch
. А в C ++ объект создается только после завершения его конструктора. Следовательно, инициализация объекта никогда не была завершена, и он не инициализирован.
У меня нет спецификации ISO C (на которую ссылается C ++ поведение longjmp
), но C ++ 11 настоятельно рекомендует приравнять _10 _ / _ 11_ к _12 _ / _ 13_, если вы получаете неопределенное поведение:
§18.10 [support.runtime] p4:
Сигнатура функции longjmp (jmp_buf jbuf, int val) имеет более ограниченное поведение в этом международном стандарте. Пара вызовов setjmp / longjmp имеет неопределенное поведение, если замена setjmp и longjmp на catch и throw вызовет любые нетривиальные деструкторы для любых автоматических объектов.
Так что я не думаю, что это недооценено. Возможно, он не будет красиво и аккуратно выложен, но все части есть.
person
Nicol Bolas
schedule
30.01.2012
longjmp
? Выход из потока может что-то изменить. - person Lightness Races in Orbit   schedule 30.01.2012static
переменным. Вы можете задать то же самое для любого другого объекта: как узнать, инициализирован ли объект, если не генерируется исключение? - person Kerrek SB   schedule 30.01.2012longjmp
, сигналы,ExitThread
среди прочего. Кроме того, это характерно для _3 _ / _ 4_ локальных переменных, поскольку они будут полностью инициализированы только один раз. Другие объекты всегда будут инициализироваться снова и снова (поскольку они всегда уничтожаются). - person Xeo   schedule 30.01.2012longjmp
илиExitThread
вне любой конструкции объекта, у вас проблемы, не так ли? Разве это не всегда УБ? - person Kerrek SB   schedule 30.01.2012longjmp
, да. См. Абзац, который я упомянул в ответ на «Легкость». Однако, как уже было сказано, автоматические объекты будут инициализироваться снова каждый раз при передаче их объявления, чего нельзя сказать о статических и локальных для потока (которые, кстати, являются неявно статическими) локальными объектами. Я просто хочу знать, когда построение будет повторено, в основном, чтобы дать адекватный ответ на связанный вопрос. :) - person Xeo   schedule 30.01.2012