【发布时间】:2015-05-28 15:37:23
【问题描述】:
有一个全局变量,我不希望任何人,而是一个 ISR 函数,来改变,变量是 g_epoch,所以看下面的代码:
#include <stdint.h>
volatile const uint32_t g_epoch = 0;
void adc_ISR() {
static uint32_t epoch = 0;
++epoch;
*(const_cast<uint32_t*>(&g_epoch)) = epoch; // Expecting g_epoch to change
printf("g_epoch adr: %x, const_casted adr: %x, epoch: %x, g_epoch: %x\n",
(uint32_t)(&g_epoch),
(const_cast<uint32_t*>(&g_epoch))),
epoch,
g_epoch);
}
输出是:g_epoch adr: ACF8, const_casted adr: ACF8, epoch: 28, g_epoch: 0,为什么 g_epoch 仍然为零?上面是清理过的函数,但代码编译时没有警告。
编辑:基于 cmets,变量被放入 ROM 区域,因此无法更改,谢谢 zneak。但看起来我可以通过使用 pragma 并将变量强制放入 RAM 来使其工作,但由于 Alessandro Pezzato 的回答,我不会,因为行为未定义。
【问题讨论】:
-
尝试修改 const is undefined behavior
-
不确定这是否只是清理,也不能真正提供答案,但您的 printf 混淆了 epoch 和 g_epoch,因此您的输出可能会产生误导。
-
您的编译器可能将变量放在只读内存中。如果您的 CPU 能够检测到非法访问,您的程序可能会崩溃。 (另外,考虑使用
%p打印指针,而不是将指针转换为uint32_t)。 -
lordjeb,谢谢,很卫生,我正在使用的 mcu 上没有 printf,我把它变成熟悉的输出时出错了。
-
嗯。看起来它应该工作。未消毒的版本呢?差异可能是关键。另外,您所说的输出是来自经过净化的版本,还是未经净化的?
标签: c++