如何在C++中通过interpret_cast将非const变量强制转换为常量静态积分类成员变量



我正在读一本关于为微控制器编写现代C++代码的书;实时C++";。我正试着自己把代码写进书中。然而,当我从书中复制代码并试图构建它时,我得到了一个编译错误:

错误C2131:表达式未计算为常量
消息:遇到一个非常量(子(表达式

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

#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 */

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

目前尚不清楚reinterpret_cast背后的意图是什么,但程序格式不正确。

变量的constexpr要求初始值设定项是常量表达式。但是,如果一个表达式要计算reinterpret_cast,那么它就不符合常量表达式的条件。因此,初始化不正确。

然而,初始化中没有任何其他内容可以阻止它成为一个常量表达式,因此

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

CCD_ 4无论如何都将是冗余的,因为它将在指定为产生相同值的相同指针类型之间进行强制转换。

GCC、ICC和MSVC在v19.16之前似乎确实错误地接受了该代码(https://godbolt.org/z/YKjhxqo3v)。也许作者只在其中一个编译器上测试了代码。

对于GCC,这里有一个错误报告。

最新更新