为什么reinterpret_cast不是constexpr? [英] Why is reinterpret_cast not constexpr?

查看:131
本文介绍了为什么reinterpret_cast不是constexpr?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下代码段:

static constexpr uint8_t a = 0;
static constexpr const int8_t *b = reinterpret_cast<const int8_t *>(&a);

这无法用error: a reinterpret_cast is not a constant expression进行编译,因为 C ++标准禁止使用 constexpr中的reinterpret_cast.

This fails to compile with error: a reinterpret_cast is not a constant expression, because the C++ standard forbids using reinterpret_cast in constexpr.

但是,如果我要将值b存储在 (对于AVR微控制器):

However compilation succeeds if I want to store the value b in PROGMEM (for AVR microcontrollers):

static constexpr uint8_t a = 0;
static const int8_t PROGMEM *const b = reinterpret_cast<const int8_t *>(&a);

在这种情况下,编译器能够证明表达式reinterpret_cast<const int8_t *>(&a)是编译时常量,因为它将结果(指向包含零的某个字节的地址的地址)插入二进制程序中的程序空间:

In this case the compiler is able to prove that the expression reinterpret_cast<const int8_t *>(&a) is compile-time constant, since it inserts its result (an address pointing to some byte containing a zero) into program space in the binary:

_ZL1g:
  .zero   1
  .section        .progmem.data,"a",@progbits
  .type   _ZL1b, @object
  .size   _ZL1b, 2
_ZL1b:
  .word   _ZL1g

此外,我的理解是reinterpret_cast是一个编译时指令.那么为什么它不能在constexpr内部使用?

Also, my understanding is that reinterpret_cast is a compile-time directive. So how come it can't be used inside a constexpr?

推荐答案

在运行时,C ++语言具有未定义行为的概念.在某些(明确指定)的条件下,该程序具有未定义的行为,这意味着它可以表现出任何行为:它可以崩溃,可以永远挂起,可以打印出乱码,可以工作或者可以执行任何操作.为何会出现这种情况的简单解释是性能.

At runtime the C++ language has the concept of Undefined Behavior. Under certain (well specified) conditions, the program has Undefined Behavior, that means that it can exhibit any behavior: it can crash, it can hang forever, it can print gibberish, it can appear to work, or it can do anything. A simplified explanation of why this exists is performance.

在运行时这是一个折衷(如果可以的话,这是一个折衷方案),但是在编译时是不可接受的.如果该标准允许在编译时使用UB,那么不仅在编译程序或无限编译时崩溃是合法的,而且您永远不能确定编译后的可执行文件的有效性.

At runtime this is a tradeoff (a compromise if you will), but it is unacceptable at compile time. If the standard would allow UB at compile time, not only it would be legal to get crashes while compiling the program or compile ad infinitum, but you could never be sure of the validity of the compiled executable.

因此,constexpr的任何形式都必须100%没有未定义的行为.没有例外.没有回旋余地.

As such, any form of constexpr would have to be 100% free of Undefined Behavior. No exceptions about it. No leeway.

UB的一个臭名昭著的来源是reinterpret_cast. reinterpret_cast的有效用法很少,其中大多数会导致UB.另外,几乎不可能检查使用是否有效.因此reinterpret_cast在编译过程中是不允许的,即在constexpr中是不允许的.

One notorious source of UB is reinterpret_cast. There are very few valid uses of reinterpret_cast, most of them result in UB. Plus it is practically impossible to check if the use is valid. So reinterpret_cast is not allowed during compilation, i.e. it is not allowed in constexpr.

这篇关于为什么reinterpret_cast不是constexpr?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆