С++ 14 имеет правила для того, что вы можете и чего не можете сделать в constexpr
. Некоторые из них (нет asm
, без статических переменных) кажутся довольно разумными. Но Стандарт также запрещает goto
в функциях constexpr
, даже если он допускает другие механизмы потока управления.
Каковы причины этого различия?
Я думал, что мы прошли "goto трудно для компиляторов".
Зачем отказываться от функции constexpr?
Ответ 1
Мое понимание заключается в желании получить расслабленную семантику constexpr
в С++ 14. Многие ограничения, которые были смягчены, были простыми, но некоторые из них были более спорными или сложными или [вставить прилагательное по вашему выбору здесь]. Вместо того, чтобы успокоить constexpr
только для возможности использовать goto
, было решено просто опубликовать основные изменения и отложить остальные. Это кажется довольно хорошим выбором, так как constexpr
в С++ 14 намного более силен, чем constexpr
в С++ 11, и неспособность использовать goto
- довольно незначительное отсутствие, все рассмотрено.
Тем не менее, конечно, существует мнение, что использование контекста goto
in constexpr
является полезным и возможным. Действительно, начальное предложение для расслабления constexpr
допустило это. Поэтому, возможно, все, что требуется, это тот, кто хочет, чтобы он написал предложение о его добавлении. Это кто-то из вас мог быть! был, видимо, Ville Voutilainen два года назад в N4472, относящийся к этому вопросу:
Есть необоснованные слухи, согласно которым запрет goto в постоянных выражениях больше по причинам вкуса, чем по техническим причинам, что означает, что поддержка goto в постоянных выражениях не особенно сложно реализовать. Я не могу сказать, правильно ли это для реализаций.
Бумага имела смешанный прием, но теперь, когда у нас есть constexpr lambdas, возможно, ее нужно пересмотреть. И чтобы кто-то мог быть вами!
Ответ 2
Ожидается, что constexpr
будет оцениваться передним концом компилятора в некотором псевдо-интерпретированном режиме или в абстрактном синтаксическом дереве, построенном за один проход, до создания любого исполняемого кода. Мы знаем, что goto
может перейти к некоторой части в конце функции, которая еще не была оценена. Следовательно, правильное подключение вызова и выполнение goto
приведет к построению АСТ за несколько проходов и выпрыгивание из строя между узлами в дереве по-прежнему является грязной операцией, которая может разорвать некоторое состояние. Так что такая конструкция не стоит проблем.