gpt4 book ai didi

c++ - constexpr 函数中的复合赋值 : gcc vs. clang

转载 作者:IT老高 更新时间:2023-10-28 22:14:21 24 4
gpt4 key购买 nike

template<class A, class B> constexpr int f(A a, B b) {
a /= b;
return a;
}

constexpr int x = f(2, 2); // a, b: int
constexpr int y = f(2., 2.); // a, b: double
constexpr int z = f(2, 2.); // a: int, b: double //<-- BOOM!
constexpr int w = f(2., 2); // a: double, b: int

int main() {}

代码未在 clang 中编译,它会产生以下诊断信息:

error: constexpr variable 'z' must be initialized by a constant expression

MSVC 崩溃(根据 godbolt )并且 gcc 工作正常。如果 a/= b 被简单地替换为 a = a/b 那么每个人都接受它。为什么?

谁是对的?似乎它与隐式缩小转换有关,但是为什么 a = a/b 有效?

最佳答案

如果我们查看复合赋值 [expr.ass]p7,这只是一个 clang 错误。它相当于 E1 只计算一次的赋值:

The behavior of an expression of the form E1 op= E2 is equivalent to E1 = E1 op E2 except that E1 is evaluated only once. In += and -=, E1 shall either have arithmetic type or be a pointer to a possibly cv-qualified completely-defined object type. In all other cases, E1 shall have arithmetic type.

如果我们查看 [dcl.constexpr]p3 中对常量表达式函数要求的限制我们对分配没有任何限制:

The definition of a constexpr function shall satisfy the following requirements:

  • (3.1) its return type shall be a literal type;
  • (3.2) each of its parameter types shall be a literal type;
  • (3.3) its function-body shall not contain.
  • (3.3.1) an asm-definition,
  • (3.3.2) a goto statement,
  • (3.3.3) an identifier label ([stmt.label]),
  • (3.3.4) a definition of a variable of non-literal type or of static or thread storage duration or for which no initialization is performed.
    [ Note: A function-body that is = delete or = default contains none of the above. — end note  ]

[expr.const] 中什么也没有为这种特定情况添加限制。

我离线联系了 Richard Smith,他同意这是一个错误并说:

Yes, it's a bug; that code is not correctly taking into account that the LHS could need conversion to floating point before the computation.

归档 clang bug reportMSVC bug report

关于c++ - constexpr 函数中的复合赋值 : gcc vs. clang,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53570652/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com