const_cast 在常量表达式中有效吗? (C++14, C++17)

Is const_cast valid in a constant expression? (C++14, C++17)

a 遇到的具体问题是编译器处理它的方式存在一些不一致。

例如这段代码 (https://godbolt.org/z/08Z-zi):

    constexpr auto value = 1;
    static_assert(*const_cast<int *>(&value), "value should be 1");

使用 GCC、Clang 和 MSVC 编译良好,但使用英特尔 C++ 编译器 19.0.1 失败并出现以下错误:

error: expression must have a constant value
static_assert(*const_cast<int *>(&value), "value should be 1");

据我所知,该标准并未明确声明常量表达式中不允许使用 const_cast。通过结果指针写入将是未定义的,因此不允许,但读取应该没问题。

考虑到所有主要编译器都编译此代码(包括 ICC < 19.0.1),它可能只是 ICC 19.0.1 中的回归。

在 C++ 中常量表达式中可能出现或不出现的内容由表达式的黑名单或表达式的属性定义。完整列表在 [expr.const 部分的第 2 段中。列表中没有任何内容禁止 const_cast 本身。据我所知,唯一相关的部分是 §2.7

an lvalue-to-rvalue conversion unless it is applied to

  • a non-volatile glvalue of integral or enumeration type that refers to a complete non-volatile const object with a preceding initialization, initialized with a constant expression, or

  • a non-volatile glvalue that refers to a subobject of a string literal, or

  • a non-volatile glvalue that refers to a non-volatile object defined with constexpr, or that refers to a non-mutable subobject of such an object, or

  • a non-volatile glvalue of literal type that refers to a non-volatile object whose lifetime began within the evaluation of e;

左值到右值的转换是(大致)"reading an object's stored value" 的标准。这就是你的例子所做的。现在,这些通常不会出现在常量表达式中。上述项目符号之一适用时除外。

第三个项目符号适用于您的案例。 * 运算符产生一个左值。所述左值不是易变的,并且指的是constexpr对象(value)。因此,您的代码是有效的 C++。