Код ниже, это плохо сформированный отчет о недоставке или он правильно сформирован? - программирование
Подтвердить что ты не робот

Код ниже, это плохо сформированный отчет о недоставке или он правильно сформирован?

Clang принимает следующий код, но gcc отклоняет его.

void h() { }

constexpr int f() {
    return 1;
    h();
}

int main() {
    constexpr int i = f();
}

Вот сообщение об ошибке:

g++ -std=c++17 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
main.cpp: In function 'constexpr int f()':
main.cpp:5:6: error: call to non-'constexpr' function 'void h()'
     h();
     ~^~
main.cpp: In function 'int main()':
main.cpp:9:24: error: 'constexpr int f()' called in a constant expression
     constexpr int i = f();
                       ~^~
main.cpp:9:19: warning: unused variable 'i' [-Wunused-variable]
     constexpr int i = f();

Это вполне может иметь место, когда оба компилятора верны, если мы рассмотрим [dcl.constexpr]/5, учитывая, что f() не является константным выражением, так как не удовлетворяет [expr.const]/(4.2), как он вызывает функцию non-constexpr h. То есть код неверен, но никакой диагностики не требуется.

Еще одна возможность состоит в том, что код правильно сформирован, так как [expr.const]/(4.2) в этом случае не применяется, поскольку вызов h в f не оценивается. Если это так, то gcc неверен, а clang верен.

4b9b3361

Ответ 1

Clang это правильно. Вызов f() является константным выражением, поскольку вызов функции h() никогда не вычисляется, поэтому [dcl.constexpr]/5 не применяется. Вызов h() в теле функции f() не является constexpr поскольку ограничения на функции constexpr ничего не говорят о том, что нельзя constexpr функции non- constexpr. Действительно, функция, подобная следующей, правильно сформирована, потому что вызов ее может быть константным выражением, когда x нечетно:

constexpr int g(int x) {
    if (x%2 == 0) h();
    return 0;
}