Код ниже, это плохо сформированный отчет о недоставке или он правильно сформирован? - PullRequest
24 голосов
/ 18 апреля 2019

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 правильно.

1 Ответ

24 голосов
/ 18 апреля 2019

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

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