Tag: volatile

通过访问function访问共享内存需要`volatile`吗?

[ 编辑 ]对于背景阅读,并且要清楚,这就是我所说的: volatile关键字简介 在查看嵌入式系统代码时,我看到的最常见错误之一是省略了线程/中断共享数据的volatile。 但是我的问题是,当通过访问函数或成员函数访问变量时,是否“安全”不使用volatile ? 一个简单的例子; 在以下代码中…… volatile bool flag = false ; void ThreadA() { … while (!flag) { // Wait } … } interrupt void InterruptB() { flag = true ; } …变量flag必须是易失性的,以确保ThreadA中的读取未被优化,但是如果通过函数读取标志… volatile bool flag = false ; bool ReadFlag() { return flag } void ThreadA() { … while ( […]

所有全局变量都应该是波动合格的吗?

在这个例子中,正确性是否要求将global_value声明为volatile ? int global_value = 0; void foo () { ++ global_value; } void bar () { some_function (++global_value); foo (); some_function (++global_value); } 我的理解是volatile是“用于” 映射内存和变量的指针,可以通过信号修改 (并且强调不是为了线程安全)但是很容易想象bar可能会编译成这样的东西: push EAX mov EAX, global_value inc EAX push EAX call some_function call foo inc EAX push EAX call some_function mov global_value, EAX pop EAX 这显然不正确,但即使没有volatile我认为根据C抽象机器它是有效的。 我错了还是有效? 如果是这样,在我看来, volatile常常被忽视。 […]

静态全局变量和静态volatile变量之间有什么区别?

我在文件范围中使用了静态全局变量和静态volatile变量, 两者都由ISR和主循环更新,主循环检查变量的值。 在优化过程中,全局变量和volatile变量都不会被优化。 因此,全局变量不是使用volatile变量,而是解决问题。 那么使用全局变量而不是volatile是好的吗? 使用静态volatile的任何具体原因?? 任何示例程序都是可观的。 提前致谢..

C / C ++:抛弃挥发性被认为有害吗?

(与此问题相关, 是否可以安全地抛出易失性?但不完全相同,因为该问题与特定实例有关) 有没有一种情况下抛弃volatile 不被视为危险的做法? (一个特定的例子:如果声明了一个函数 void foo(long *pl); 我必须实施 void bar(volatile long *pl); 我的实现的一部分需要bar()来调用foo(pl),然后好像我不能让它按原样工作,因为foo()的编译和bar的调用者的编译所做的假设()不兼容。) 作为必然结果,如果我有一个volatile变量v,并且我想用别人的函数void foo(long *pl)调用foo(&v) void foo(long *pl) ,那个人告诉我它是安全的,我可以在调用之前转换指针,我的本能是告诉他们他们错了,因为没有办法保证,如果他们想支持使用volatile变量,他们应该将声明改为void foo(volatile long *pl) 。 我们哪一个是正确的?

通过易失性引用/指针访问声明的非易失性对象是否会在所述访问时赋予易失性规则?

这将是一个漫长的过程,关于它的上下文并提供尽可能多的信息,我必须蜿蜒通过各种链接和引用 – 这通常是我们进入C / C ++标准兔子洞后的唯一方法。 如果您对此帖有更好的引用或任何其他改进,请告诉我。 但是要事先总结一下, 你可以责怪@ zwol发布这个;-)并且目的是从两个命题中找到真相: 执行C和(通过导入;请参阅注释)C ++标准要求通过volatile *或volatile &访问必须引用最初声明为volatile的对象才能具有volatile语义? 或者是通过volatile指针/引用访问非易失volatile限定对象/应该使所述访问行为就像对象被声明为volatile ? 无论哪种方式,如果(看起来)措辞与意图相比有些含糊不清 – 我们可以在标准本身中明确说明吗? 这些相互排斥的解释中的第一个更常见,而且并非完全没有依据。 但是,我希望表明有大量的“合理怀疑”支持第二个 – 特别是当我们回到基本原理和WG论文中的一些先前的段落时。 接受的智慧:被引用的对象本身必须被声明为volatile 昨天流行的问题是“挥发性”这个波动的定义,还是GCC有一些标准的合规性问题? 通过假设一个volatile引用会给volatile volatile指示物带来volatile行为 – 但发现它没有,或者在不同程度上以不可预测的方式做出来。 接受的答案最初得出结论,只有宣称的指称类型才重要。 这个和大多数注释似乎都同意等效原则在我们对const很熟悉的情况下起作用:如果引用具有与引用对象相同的cv -qualification,则行为将只是volatile (或根本定义): 该段落中的关键词是对象。 volatile sig_atomic_t flag; 是一个易变的对象。 *(volatile char *)foo仅仅是通过volatile限定左值的访问,标准不要求具有任何特殊效果 。 – zwol 这种解释似乎被广泛持有,正如对这个相似但希望不重复的问题的回答所示: 指向易失性指向非易失性对象的行为要求但即使存在不确定性:紧接着答案是’不’,然后说’也许’! 无论如何……让我们检查一下标准,看看’没有’是什么。 标准所说的……或者不是 C11, N1548,§6.7.3 :很明显,通过不共享所述限定符的指针访问用 volatile或const类型定义的对象是UB … 6如果尝试通过使用具有非const qualifiedified类型的左值来修改使用const限定类型定义的对象,则行为未定义。 […]

在主程序和C中的ISR之间共享volatile变量是否安全?

在主程序和C中的ISR之间共享一个对齐的整数变量(不大于处理器自然字,使用volatile限定符)是否安全? 是否保证不会发生撕裂的读写操作?

“volatile”限定符和编译器重新排序

编译器不能消除或重新排序对volatile限定变量的读/写。 但是,存在其他变量的情况又如何,可能是也可能不是volatile ? 情景1 volatile int a; volatile int b; a = 1; b = 2; a = 3; b = 4; 编译器可以重新排序第一个和第二个,第三个和第四个赋值吗? 场景2 volatile int a; int b, c; b = 1; a = 1; c = b; a = 3; 同样的问题,编译器可以重新排序第一个和第二个,或第三个和第四个分配?