问题描述
为了类型安全和命名空间功能,我想尽可能使用 constexpr
而不是 #define
。
不幸的是,我在尝试时得到了这个 error: 'reinterpret_cast<SPI_TypeDef*>(1073756160)' is not a constant expression
。
#include <stm32f0xx.h> // #defines SPI2 as pointer to a struct of volatile unsigned ints
constexpr auto myPort = SPI2;
我不想要解释为什么 reinterperet_cast
不能用在 constexpr
中。
使用 constexpr 指针指向某些内存映射硬件的现代 C++ 方法是什么?
这样做的一个原因是在模板代码中使用这些 constexpr
值。
解决方法
constexpr
代码不是为了避免使用 #define
而发明的;它在那里,所以你可以用表达式做一些你不能做的事情。例如,您可以将 constexpr
指针或整数作为模板参数传递,因为它们是常量表达式。
基本上,任何 constexpr
变量或函数的主要目的是能够在编译时编程中使用。因此,将变量声明为 constexpr
就是说“这是一个编译时常量,在编译时使用它是合理的。”
不能在编译时使用值为任意地址的指针。所以将这样的指针标记为编译时值是一个矛盾。所以你不允许这样做。 constexpr
指针必须是真正的指针,要么是空指针,要么指向实际对象。不是任意地址。
这不可能。甚至 std::bit_cast
在某些情况下可以在编译时模拟 reinterpret_cast
,当涉及的类型之一是指针时 loses its constexpr-ness。
就像其他答案已经说明的那样,任意指针是不可能的。
如果它是“为了类型安全和命名空间特性 [...] 到一些内存映射硬件”,你为什么不直接使用
// assumed preconditions,since not provided in question
typedef struct {
volatile unsigned int a;
volatile unsigned int b;
} SPI_TypeDef;
SPI_TypeDef* SPI2 = (SPI_TypeDef*)0x12345678;
// actual answer
SPI_TypeDef* const myPort = SPI2;
这样你的指针 myPort 指向一些结构体SPI_TypeDef 类型的数据是常量,而不是指向的结构体。
const
关键字通常是“左分配”。