在 C++ 中的微控制器上执行转换为较小类型的推荐方法
Recommended way to perform a cast to a smaller type on micro controller in C++
我正在为基于 32 位微控制器的 Arduino Due 编程。我想读取一个 ADC 结果寄存器(如果我是对的,它的宽度为 32 位,但它的真正最大宽度为 12 位,这是 ADC 的分辨率),并将其写入数组中的给定位置宽度为 16 位的整数。
这个有效:
volatile uint16_t Buf[nchannels];
[... some code...]
void ADC_Handler() {
for (int i = 0; i < nchannels; i++)
{
Buf[i] = (volatile uint16_t) * (ADC->ADC_CDR + channels[i]); // my modification
}
FlagConversion = true;
}
但是使用更“显式”的演员表是行不通的:
Buf[i] = dynamic_cast<volatile uint16_t *>(ADC->ADC_CDR + channels[i]);
产生:
“错误:不能dynamic_cast '(((RoReg*)1074528336) + ((sizetype)(((unsigned int)channels[i]) * 4)))'(类型'RoReg* {aka volatile long unsigned int*}') 键入 'volatile uint16_t* {aka volatile short unsigned int*}'(目标不是指针或对 class 的引用)"
以及静态和重新解释转换的类似不明确错误:
“错误:不能dynamic_cast '(((RoReg*)1074528336) + ((sizetype)(((unsigned int)channels[i]) * 4)))'(类型'RoReg* {aka volatile long unsigned int*}') 键入 'volatile uint16_t* {aka volatile short unsigned int*}'(目标不是指针或对 class 的引用)"
和
“错误:从 'volatile uint16_t* {aka volatile short unsigned int*}' 到 'uint16_t {aka short unsigned int} 的无效转换”
- 知道为什么这些更明确的转换会失败吗?
- 这里的最佳做法是什么?
进行转换的'safe'方法是首先取消引用指向 32 位数据的指针,然后屏蔽掉该数据项的高 16 位,然后 static_cast
结果到您的 16 位目标数据:
Buf[i] = static_cast<volatile uint16_t>( *(ADC->ADC_CDR + channels[i]) & 0x0FFFF );
最好始终使用 'simplest' 形式的转换,并尽可能避免使用 C-style 转换和 reinterpret_cast
。在这种情况下,强制转换指针没有什么意义,而且 比 convert/cast 数据本身更安全和更简单。
实际上,0x0FFFF
的屏蔽严格来说是完全不必要和多余的。但是,它让您的代码的任何未来 reader 清楚地知道您确实知道自己在做什么!
我正在为基于 32 位微控制器的 Arduino Due 编程。我想读取一个 ADC 结果寄存器(如果我是对的,它的宽度为 32 位,但它的真正最大宽度为 12 位,这是 ADC 的分辨率),并将其写入数组中的给定位置宽度为 16 位的整数。
这个有效:
volatile uint16_t Buf[nchannels];
[... some code...]
void ADC_Handler() {
for (int i = 0; i < nchannels; i++)
{
Buf[i] = (volatile uint16_t) * (ADC->ADC_CDR + channels[i]); // my modification
}
FlagConversion = true;
}
但是使用更“显式”的演员表是行不通的:
Buf[i] = dynamic_cast<volatile uint16_t *>(ADC->ADC_CDR + channels[i]);
产生:
“错误:不能dynamic_cast '(((RoReg*)1074528336) + ((sizetype)(((unsigned int)channels[i]) * 4)))'(类型'RoReg* {aka volatile long unsigned int*}') 键入 'volatile uint16_t* {aka volatile short unsigned int*}'(目标不是指针或对 class 的引用)"
以及静态和重新解释转换的类似不明确错误:
“错误:不能dynamic_cast '(((RoReg*)1074528336) + ((sizetype)(((unsigned int)channels[i]) * 4)))'(类型'RoReg* {aka volatile long unsigned int*}') 键入 'volatile uint16_t* {aka volatile short unsigned int*}'(目标不是指针或对 class 的引用)"
和
“错误:从 'volatile uint16_t* {aka volatile short unsigned int*}' 到 'uint16_t {aka short unsigned int} 的无效转换”
- 知道为什么这些更明确的转换会失败吗?
- 这里的最佳做法是什么?
进行转换的'safe'方法是首先取消引用指向 32 位数据的指针,然后屏蔽掉该数据项的高 16 位,然后 static_cast
结果到您的 16 位目标数据:
Buf[i] = static_cast<volatile uint16_t>( *(ADC->ADC_CDR + channels[i]) & 0x0FFFF );
最好始终使用 'simplest' 形式的转换,并尽可能避免使用 C-style 转换和 reinterpret_cast
。在这种情况下,强制转换指针没有什么意义,而且 比 convert/cast 数据本身更安全和更简单。
实际上,0x0FFFF
的屏蔽严格来说是完全不必要和多余的。但是,它让您的代码的任何未来 reader 清楚地知道您确实知道自己在做什么!