g cc и clang расходятся во мнениях относительно того, является ли выражение вычисленным константой - PullRequest
14 голосов
/ 09 июля 2020

Для следующей программы:

struct S { int i; };

constexpr S f() { 
  return std::is_constant_evaluated() ? S{1} : S{0}; 
}

int main() {
  S s = f();
  return s.i;
}

g cc возвращает 0, а clang возвращает 1. demo

Я не думаю, что оценка f выполняется в контексте, требующем постоянной оценки, поэтому я думаю, что clang здесь неправильный. Или все наоборот? Или оба результата верны?

1 Ответ

13 голосов
/ 09 июля 2020

Требование, которое мы ищем, - это если выражение явно вычисляется константой , что определено в [expr.const] / 14 , то есть:

  • a constant-expression , или
  • условие выражения constexpr if ([stmt.if]), или
  • an немедленный вызов, или
  • результат подстановки в выражение ограничения atomi c, чтобы определить, выполняется ли оно ([temp.constr.atomic]), или
  • инициализатор переменной который может использоваться в постоянных выражениях или имеет постоянную инициализацию.

Очевидно, что первые четыре из этих условий не выполняются.

Для последнего из них наша переменная не может использоваться в константных выражениях, поскольку не является constexpr и не имеет целочисленного / перечислимого типа с квалификацией const. Итак, это первая половина пятого условия.

Для последней части последнего, нам нужно определить, есть ли у нас постоянная инициализация (не путать с постоянной инициализацией ). Это определение находится в [basi c .start.static] / 2 , акцент мой:

Постоянная инициализация выполняется, если переменная или временная объект со статусом c или длительностью хранения потока инициализируется константой ([expr.const]).

Но s это не a переменная со stati c или длительностью хранения потока, поэтому нет постоянной инициализации, поэтому последняя часть последнего условия также не выполняется.

Следовательно, ни одно из условий не выполняется, и в OP , std::is_constant_evaluated() должен вернуть false, и это ошибка clang.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...