Почему ложная ветвь if constexpr компилируется?

Почему этот код выдает ошибку при компиляции? Мои знания (а также это) if constexpr говорит, что блок else не должен компилироваться.

if constexpr (true) {
    int a = 10;
} else {
    int b = 10
}

Ошибка:

error: expected ‘,’ or ‘;’ before ‘}’ token

Используемый компилятор: g++ версии 7.5.0
При компиляции я использовал флаг -std=c++17.

P.S. Отсутствует ';' намеренно, просто чтобы проверить, компилируется ли else или нет.


person Kishan Shukla    schedule 18.08.2020    source источник
comment
Возможно, вам следует явно указать, что отсутствующий ; является целеустремленным; по крайней мере, это кажется мне вашим намерением (я полагаю, чтобы проверить, компилируется ли блок else).   -  person User 10482    schedule 18.08.2020
comment
Существует огромная разница между тем, чтобы не компилировалось (или не создавалось экземпляр) и не анализировалось.   -  person Eljay    schedule 18.08.2020
comment
Это вполне резонный вопрос, и цель фрагмента кода ясна.   -  person cigien    schedule 19.08.2020


Ответы (1)


Здесь есть 2 отдельных, но связанных вопроса.

Во-первых, if constexpr будет только условно компилировать ветку в шаблоне. Вне шаблона все ветки будут скомпилированы и должны быть правильно сформированы.

Во-вторых, даже в шаблоне отброшенная ветвь if constexpr не может быть неправильно сформирована для всех возможных инстанций. Это не так в вашем коде, так как:

int b = 10

всегда имеет неправильный формат (из-за отсутствия ;).

Таким образом, компилятор прав, выдавая ошибку компиляции. Технически, если отброшенная ветвь имеет неправильный формат для всех экземпляров, то компилятор не обязан выдавать ошибку компилятора, но код по-прежнему неверен.

person cigien    schedule 18.08.2020
comment
Спасибо за быстрый ответ. Можете ли вы объяснить немного больше о шаблоне? - person Kishan Shukla; 18.08.2020
comment
Также второй случай — NDR. - person T.C.; 18.08.2020
comment
@KishanShukla if constexpr ведет себя как шаблон. Ложная ветвь по-прежнему компилируется, но не всегда создается экземпляр. Если зависимых типов нет, то проверяются на валидность все разветвленные. Это не похоже на препроцессор. - person Guillaume Racicot; 18.08.2020
comment
@KishanShukla См. ссылку. Есть пример, в котором показано, что if constexpr должен зависеть от T внутри template<typename T>, чтобы одна из ветвей была отброшена. - person cigien; 18.08.2020
comment
@T.C.: Это правда? Он даже не выполняет анализ, поэтому я не уверен, что мы достигнем уровня анализа, который «проверяет» возможное создание экземпляра. - person Davis Herring; 18.08.2020
comment
@DavisHerring В прошлый раз, когда я проверял, мы все еще разрешаем реализацию токен-супа. - person T.C.; 18.08.2020
comment
@T.C.: Не имея определения для создания экземпляра, я не могу сказать, должен ли плохой синтаксис быть его частью. Грамматика, безусловно, «видит» все, даже если известная техника реализации соответствует только {…} в этом случае. - person Davis Herring; 18.08.2020
comment
@DavisHerring [temp.res]/8 имеет такой же пример без синтаксического анализа. / пожимает плечами - person T.C.; 18.08.2020
comment
Да, там написано, что void g(T t) { +; } может быть диагностировано, так что, кажется, это не требуется, даже если синтаксический анализ завершится ошибкой. - person cigien; 18.08.2020
comment
Отсутствие точки с запятой, вероятно, приводит к сбою компиляции уже на этапе лексирования или сразу после него. . В этот момент у выражения в предложении if не было возможности выполниться. - person bitmask; 19.08.2020