【问题标题】:Is const_cast valid in a constant expression? (C++14, C++17)const_cast 在常量表达式中有效吗? (C++14, C++17)
【发布时间】:2019-08-22 09:30:37
【问题描述】:

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

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

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

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

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

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

考虑到所有主要编译器都编译此代码(包括 ICC

【问题讨论】:

    标签: c++ language-lawyer constexpr const-cast constant-expression


    【解决方案1】:

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

    左值到右值的转换,除非它被应用于

    • 一个整数或枚举类型的非易失性左值,它引用一个完整的非易失性 const 对象,前面有一个 初始化,用常量表达式初始化,或

    • 引用字符串字面量的子对象的非易失性泛左值,或

    • 一个非易失性泛左值,它引用一个用 constexpr 定义的非易失性对象,或者引用一个这样的一个非可变子对象 对象,或

    • 文字类型的非易失性左值,它引用一个非易失性对象,其生命周期在e的评估内开始;

    左值到右值的转换是标准的(大致)“读取对象的存储值”。这就是您的示例所做的。现在,这些通常不会出现在常量表达式中。除非前面的项目符号之一适用。

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

    【讨论】:

      猜你喜欢
      • 2016-08-02
      • 1970-01-01
      • 2017-01-05
      • 2020-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多