提问人:Cameron Tacklind 提问时间:2/2/2019 最后编辑:Cameron Tacklind 更新时间:3/17/2022 访问量:481
现代 C++ 将 constexpr const 指针指向嵌入式应用程序的易失性内存位置的方法是什么?
What is the modern C++ way of having a constexpr const pointer to a volatile memory location for embedded applications?
问:
在嵌入式微处理器上构建用于控制硬件的库时,一个常见的任务是操作特定内存位置的位以控制硬件功能。
在 AVR 处理器中,Atmel(现在的 Microchip)提供了扩展为如下内容的宏:
#define PORTA (*(volatile uint8_t *)(0x25))
这样可以实现以下功能:
PORTA |= 1;
现在在 C++11(和更新版本)中,几乎任何用法都替换为 。#define
constexpr
在旧版本的 GCC C++ 编译器 (4.9.2) 中,编译了以下内容:
#include <avr/io.h>
constexpr volatile uint8_t *const PortA = &PORTA;
在版本 8.2.0 中,上述内容无法编译并给出错误:
error: 'reinterpret_cast<volatile uint8_t* {aka volatile unsigned char*}>(37)' is not a constant expression
我不是在寻找为什么你不能在上下文中使用或为什么整数到指针的转换是非法的解释。reinterpret_cast
constexpr
在现代 C++ 中拥有指向易失
性内存的 constexpr
指针的正确方法是什么?
我已经看到将内存地址存储在 a 中然后在运行时将其用于位操作的建议。PORTA
constexpr uintptr_t
reinterprect_cast
volatile uint8_t * const
例如,这可以工作,甚至可以按预期编译为单个指令。sbi
avr-gcc
#include <stdint.h>
constexpr uintptr_t PortA = 0x25;
void set() { *((volatile uint8_t *)(PortA)) |= 1; }
但是,它需要相当数量的丑陋样板才能用作它预期的指针。PortA
这也有一个问题,似乎无法直接使用宏。相反,我们被迫对内存地址进行硬编码,这破坏了某些理想的可移植性功能。PORTA
0x25
感觉我错过了一些明显的东西,购买我的搜索没有产生任何成果。
例如,这感觉像是一个“地址常量表达式”,但这似乎与引用静态分配的值有关,例如这不是我想要的。const
const char str[] = "FooBar";
constexpr const char * x = str + 2;
答:
不能创建由非常量表达式初始化的 constexpr 指针。但是,您可以创建一个指针:static const
static uint8_t volatile* const PortA = &PORTA;
或者,更好的是,参考:static
static uint8_t volatile& PortA = PORTA;
评论
error: reinterpret_cast from integer to pointer
error: value ‘37’ of type ‘volatile uint8_t* {aka volatile unsigned char*}’ is not a constant expression
volatile uint8_t& PortA = PORTA;
constexpr
reinterpret_cast