Я не адвокат по языку, но это должно не компилироваться. Вы пытаетесь инициализировать значение с самим собой во время компиляции. Я предполагаю, что это лягушатник. На самом деле, я не понимаю, почему GCC должен следовать по пути рекурсии, если он попадает в цикл.
Кстати, MSVC говорит вам (GodBolt):
<source>(14): note: see reference to class template instantiation 'foo<int,int>' being compiled
что является правильным уловом. На этот раз MSVC затмевает другие компиляторы ...: -P
edit: @aschepler отмечает, что мы получаем (GodBolt) такое же поведение даже без шаблонов:
struct bar { static const bool value = !bar::value; };
другое редактирование : Кажется, еще несколько лет назад это был своего рода действительный код из-за "софистики языка юриста". Видите ли, стандарт раньше говорил (Раздел 6.6.2 [basic.start.static] параграф 2):
Переменные со статической продолжительностью хранения ... должны быть инициализированы нулями ... до того, как произойдет любая другая инициализация.
и clang принял это, чтобы означать, что сначала вы все инициализируете нулями, а затем учитываете инициализации статической длительности - это означает, что bar::value
неявно decltype(bar::value) { 0 }
перед его собственной явной инициализацией. Это было изменено после сообщения о дефекте 2026 .
Кредит за указание на это идет Ричард Смит .