如何在 C++ 中通过 reinterpret_cast 将非常量变量转换为常量静态整数 class 成员变量?

How to cast nonconst variable to constant static integral class member variable via reinterpret_cast in C++?

我正在阅读一本关于为微控制器编写现代 C++ 代码的书,书名是“Real time C++”。我正在尝试自己编写书中的代码。然而,在从书中复制代码并尝试构建它时,我得到了一个编译错误:

error C2131: expression did not evaluate to a constant.
message : a non-constant (sub-) expression was encountered

我插入了下面代码的相关部分:

#include <cstdint>
#include <iomanip>
#include <iostream>
namespace mcal
{
  namespace reg
  {
    // Simulate the transmit and receive hardware buffers on the PC.
    std::uint8_t dummy_register_tbuf;
    std::uint8_t dummy_register_rbuf;
  }
}

class communication
{
  private:
    static constexpr std::uint8_t* tbuf = reinterpret_cast<std::uint8_t*>(&mcal::reg::dummy_register_tbuf); 
    static constexpr std::uint8_t* rbuf = reinterpret_cast<std::uint8_t*>(&mcal::reg::dummy_register_rbuf);
};

/* rest of the nonrelated code */

错误指示发生转换的那两行。我知道我们尝试使用 static constexpr integral class 成员变量,因为这确保了对它们的优化(常量折叠)。我认为错误的发生是因为我们试图将一个非常量变量设置为一个常量变量,但我肯定是错的。所以,我恳请你向我解释这里真正的问题是什么,以及为什么作者会犯这样的错误(如果是错误的话)。另外,如果您另外指出正确的铸造方法,我将不胜感激。非常感谢。

尚不清楚 reinterpret_cast 背后的意图,但程序格式错误。

变量上的

constexpr 要求初始值设定项是常量表达式。但是,如果表达式计算 reinterpret_cast,则表达式不符合成为常量表达式的资格。因此初始化格式错误。

但是,初始化中没有其他任何东西阻止它成为常量表达式,因此

static constexpr std::uint8_t* tbuf = &mcal::reg::dummy_register_tbuf; 

将正常工作,而 reinterpret_cast 无论如何都是多余的,因为它会在指定为产生相同值的相同指针类型之间进行转换。

GCC、ICC 和 MSVC 直到 v19.16 似乎错误地接受了代码 (https://godbolt.org/z/YKjhxqo3v)。也许作者只在这些编译器之一上测试了代码。

对于 GCC 有一个错误报告 here