【问题标题】:Can a core constant expression contain an ignored reinterpret_cast?核心常量表达式可以包含被忽略的 reinterpret_cast 吗?
【发布时间】:2020-06-13 00:51:25
【问题描述】:

当使用 godbolt.org 在线编译器编译以下示例程序时,Clang-9.0.0 和 MSVC v19.24 都在标记为 (1) 和 (2) 的行报告错误。错误消息表明表达式 (reinterpret_cast<uintptr_t>(&x), 1) 不会计算为常量。但确实如此,不是吗?

另一方面,GCC-9.2 编译此示例时没有错误。

#include <memory>

int x;

enum
{
    Value = (reinterpret_cast<uintptr_t>(&x), 1)    // (1)
};

template <int N>
struct Test
{
};

Test<(reinterpret_cast<uintptr_t>(&x), 1)>     t;   // (2)

问题是:(reinterpret_cast&lt;uintptr_t&gt;(&amp;x), 1) 是否计算为常数?

【问题讨论】:

标签: c++ c++17 language-lawyer


【解决方案1】:

核心常量表达式不能包含 reinterpret_cast,即使它的值被丢弃(因此 MSVC 和 Clang 拒绝代码是正确的)。参见 C++17 [expr.const]/2.15:

表达式e 是一个核心常量表达式,除非e 的计算遵循抽象机的规则,将计算以下表达式之一:...reinterpret_cast

根据抽象机的规则,reinterpret_cast 必须被评估。见[expr.comma]/1:

一对用逗号分隔的表达式从左到右计算;左表达式是丢弃值表达式。与左表达式关联的每个值计算和副作用都在与右表达式关联的每个值计算和副作用之前排序。 ...

很明显,仅仅对reinterpret_cast 求值就足以使表达式不是核心常量表达式,即使它根本不影响结果。

这与演员阵容真正没有被评估的情况不同:

enum {
    Value = 1 || reinterpret_cast<uintptr_t>(&x);  // OK
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多