gcc 和 clang 不同意表达式是否常量评估
gcc and clang disagree on whether expression is constant evaluated
对于以下程序:
struct S { int i; };
constexpr S f() {
return std::is_constant_evaluated() ? S{1} : S{0};
}
int main() {
S s = f();
return s.i;
}
gcc returns 0,和 clang returns 1。demo
我不认为 f
的评估是在需要不断评估的上下文中进行的,所以我认为这里的 clang 是错误的。还是相反?或者两个结果都有效?
我们正在寻找的要求是如果表达式是 manifestly constant-evaluated, which is defined in [expr.const]/14,即:
- a constant-expression, or
- the condition of a constexpr if statement ([stmt.if]), or
- an immediate invocation, or
- the result of substitution into an atomic constraint expression to determine whether it is satisfied ([temp.constr.atomic]), or
- the initializer of a variable that is usable in constant expressions or has constant initialization.
前四个条件显然不成立。
对于最后一个,我们的变量不能用于常量表达式,因为它既不是 constexpr 也没有 const 限定的 integral/enumeration 类型。这就是第五个条件的前半部分。
对于上一个的最后一部分,我们需要确定我们是否有常量初始化(不要与被常量初始化混淆)。该定义在 [basic.start.static]/2 中,重点是我的:
Constant initialization is performed if a variable or temporary object with static or thread storage duration is constant-initialized ([expr.const]).
但是s
是不是静态或者线程存储持续时间的变量,所以没有常量初始化,所以最后一个条件的最后一部分没有要么持有。
因此,none 的条件成立,并且在 OP 中,std::is_constant_evaluated()
应该 return false
和这个是一个 clang 错误。
对于以下程序:
struct S { int i; };
constexpr S f() {
return std::is_constant_evaluated() ? S{1} : S{0};
}
int main() {
S s = f();
return s.i;
}
gcc returns 0,和 clang returns 1。demo
我不认为 f
的评估是在需要不断评估的上下文中进行的,所以我认为这里的 clang 是错误的。还是相反?或者两个结果都有效?
我们正在寻找的要求是如果表达式是 manifestly constant-evaluated, which is defined in [expr.const]/14,即:
- a constant-expression, or
- the condition of a constexpr if statement ([stmt.if]), or
- an immediate invocation, or
- the result of substitution into an atomic constraint expression to determine whether it is satisfied ([temp.constr.atomic]), or
- the initializer of a variable that is usable in constant expressions or has constant initialization.
前四个条件显然不成立。
对于最后一个,我们的变量不能用于常量表达式,因为它既不是 constexpr 也没有 const 限定的 integral/enumeration 类型。这就是第五个条件的前半部分。
对于上一个的最后一部分,我们需要确定我们是否有常量初始化(不要与被常量初始化混淆)。该定义在 [basic.start.static]/2 中,重点是我的:
Constant initialization is performed if a variable or temporary object with static or thread storage duration is constant-initialized ([expr.const]).
但是s
是不是静态或者线程存储持续时间的变量,所以没有常量初始化,所以最后一个条件的最后一部分没有要么持有。
因此,none 的条件成立,并且在 OP 中,std::is_constant_evaluated()
应该 return false
和这个是一个 clang 错误。