为啥不能在常量表达式中使用 reinterpret_cast? [复制]

Posted

技术标签:

【中文标题】为啥不能在常量表达式中使用 reinterpret_cast? [复制]【英文标题】:Why can't reinterpret_cast be used in a constant expression? [duplicate]为什么不能在常量表达式中使用 reinterpret_cast? [复制] 【发布时间】:2021-09-04 10:50:31 【问题描述】:

我遇到了以下错误:

class NormalClass

public:
    constexpr NormalClass() : arr, debug_ptr((int*)arr)
    
//'reinterpret_cast' is not a constant expression
//cast that performs the conversions of a reinterpret_cast is not allowed in a constant expression
    

public:

    char arr[5];
    int* debug_ptr;


;

constinit NormalClass normal;

int main()



最初这是在模板中,带有 (T*) 演员表。为什么在 constexpr 中不允许这样的演员表?

【问题讨论】:

编译器是否将reinterpret_cast 用于(T*) 取决于转换的类型和转换为的类型。如果它与(T*) 一起工作,那么编译器没有选择reinterpret_cast 有了标题,问题可能与Why is reinterpret_cast not constexpr? 重复您可能希望显示带有使用模板的minimal reproducible example 和(T*) 的代码,包括与演员表和您当前的示例也是如此,然后可以说明为什么一个有效而另一个无效 不是答案;但是如果你用unsigned int(或64位环境中的unsigned long)替换int*,它编译时不会出现警告。 这可能是最好的,因为不要认为这是一个有效的演员表。您将如何到达char 数组的最后一个元素? 哦,当我有自己的具有 char 缓冲区的数组容器时,它出现了,我无法通过 char 指针在调试器中看到其中的任何内容,所以我想创建一个调试指针投射到 T。 【参考方案1】:

见https://en.cppreference.com/w/cpp/language/constant_expression

核心常量表达式

核心常量表达式是其评估不会评估以下任何一项的任何表达式:

    reinterpret_cast

【讨论】:

【参考方案2】:

为什么不能在常量表达式中使用 reinterpret_cast?

因为 C++ 语言规范是这么说的。见[expr.const]/5.15:

表达式E 是一个核心常量表达式,除非E, ... 的计算会计算以下之一:

5.15   reinterpret_­cast ([expr.reinterpret.cast]);


另请注意,将 char[] 重新解释为 int 然后访问它是未定义的行为 - strict aliasing violation。在实际程序中,只要指针debug_ptr被解引用,就会有UB。

【讨论】:

那真的是我要找的那个 ;) 找不到足够快的参考。谢谢

以上是关于为啥不能在常量表达式中使用 reinterpret_cast? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

为啥在 C for 循环的条件中使用表达式而不是常量?

为啥我不能在 switch 语句中使用元组常量作为案例

为啥在未计算的操作数中不允许使用 lambda 表达式,但在常量表达式的未计算部分中允许使用 lambda 表达式?

为啥 C++ switch 语句仅限于常量表达式?

为啥这个 std::string_view 不是常量表达式?

为啥允许在这里用非 const 初始化静态变量?