我有一些示例代码(来自Nordic),其中包括下一行:
NRF_RADIO->EVENTS_END = 0;
(void)NRF_RADIO->EVENTS_END;
NRF_RADIO-> EVENTS_END是一个嵌入式寄存器,在第一行设置为0.
有人可以解释第二行的含义吗?
由于 亚龙
答案 0 :(得分:4)
第二行"仅#34;读回寄存器。它这样做,通过将(void)
强制转换为void来明确忽略读取的实际值。
该专栏有两个专业,可能会使理解变得非常重要:
1的原因很可能是(根据OP声明)涉及外设寄存器的事实。这可能意味着需要看似无用的读取的机制。例如:
2的原因完全是分开的,例如可以是:
编辑可读性和更好的结构,不改变基本逻辑;为了有希望防止误解,我认为这是两个贬低者。如果有合理的原因,请告知我们。
答案 1 :(得分:-1)
对于某些设备,读取寄存器可能会产生副作用。 例如,I / O内存:
I / O内存只是一个类似RAM的位置区域,设备通过总线提供给处理器。此存储器可用于多种用途,例如保存视频数据或以太网数据包,以及实现与I / O端口一样的设备寄存器(即,它们具有与读取和写入相关的副作用)。 / p>
以下行可能是为了激活此设备上的某种副作用:
(void)NRF_RADIO->EVENTS_END;
有时您只想从寄存器中读取数据,以使CPU等待写入数据。
然而只是在不使用数据的情况下读取数据可能会使编译器发出警告,如果使用优化,最终会完全删除此语句(如下所示)
为了演示如何在代码中添加/删除(void)
/ volatile
可能会影响生成的代码,我将在此处展示一些示例。
注意:以下示例是C / C ++的未定义行为,但在gcc + x86下定义良好。
以下程序会产生警告,但运行它不会产生分段错误,因为永远不会读取指针(编译器会认为它是多余的)。
struct example {
int b;
};
int main() {
struct example * a = NULL;
a->b;
return 0;
}
以下程序会产生警告,但运行将因使用volatile
而产生分段错误。虽然编译器知道这个位置需要直接使用,但是它不知道它可能有什么副作用。
struct example {
volatile int b;
};
int main() {
struct example * a = NULL;
a->b;
return 0;
}
以下程序不会产生任何警告,但运行 会产生分段错误。
struct example {
volatile int b;
};
int main() {
struct example * a = NULL;
(void)a->b;
return 0;
}
以下程序不会产生任何警告,并且运行 会产生分段错误。
struct example {
int b;
};
int main() {
struct example * a = NULL;
(void)a->b;
return 0;
}