Tag: volatile

函数调用之间是否刷新了全局变量?

我正在编写嵌入式固件,并发现有时很难确定何时需要使用volatile。 当我有一个等待某个布尔标志被中断改变的函数时,很明显该标志需要是易失性的,因为该函数会永远等待,因为编译器没有意识到该值可以由打断。 但是当我有一个只检查第一行中的标志的短函数时,我希望标志不需要是易失性的,因为每次进入函数时它的值都会被读取? 所以当一个中断在我第一次调用函数和第二次调用函数之间修改它的值时,我将获得最新的值。 或者是否无法保证每次进入该function时都会清除所有缓存寄存器?

相对于函数调用和返回的全局变量访问

我一直在研究这个主题,但我找不到具体的权威答案。 我希望非常熟悉C规范的人能够回答 – 即确认或驳斥我的断言,最好引用规范。 断言:如果一个程序包含多个编译单元(单独编译的源文件),编译器必须确保在调用另一个单元中的函数之前或从任何函数返回之前将全局变量(如果已修改)写入内存。 此外,在任何函数中,必须在首次使用之前读取全局。 在调用任何函数之后,不是在同一单元中,必须在使用前读取全局。 并且这些事情必须是真的,无论变量是否被限定为“volatile”,因为另一个编译单元(源文件)中的函数可以在没有编译器知识的情况下访问变量。 否则,全局变量总是需要“volatile” – 即非易失性全局变量没有任何意义。 编译器能否在同一编译单元中处理不同于未编译单元的函数? 我在全局变量上找到的“volatile”限定符的所有讨论都显示了同一编译单元中的所有函数。 编辑:编译器无法知道其他单元中的函数是否使用全局。 因此我假设上述条件。 我发现这两个问题与这个主题相关的信息,但他们没有解决它或他们提供我发现怀疑的信息: 函数调用之间是否刷新了全局变量? 我什么时候需要在ISR中使用volatile?

为什么POSIX mmap没有返回volatile void *?

Mmap返回void *,但不返回volatile void* 。 如果我正在使用mmap来映射共享内存,那么另一个进程可能正在写入该内存,这意味着来自同一内存位置的两个后续读取可能会产生不同的值 – 这意味着volatile的确切情况。 那么为什么它不会返回一个易变的空隙*? 我最好的猜测是,如果你有一个专门写入共享内存段的进程,它不需要通过volatile指针查看共享内存,因为它总能正确理解存在的内容; 编译器为防止冗余读取所做的任何优化都无关紧要,因为没有其他任何内容可以写入并更改其下的值。 还是有其他一些历史原因? 我倾向于说返回volatile void*将是一个更安全的默认值,那些想要这个优化的人可以手动转换为void *。 POSIX mmap说明: http : //opengroup.org/onlinepubs/007908775/xsh/mmap.html

InterlockedIncrement参数声明为volatile的影响是什么

InterlockedIncrement和其他Interlocked操作将其参数声明为volatile。 为什么? 这是什么意图和影响?

我怎么知道gcc是否同意某些东西是不稳定的?

考虑以下: volatile uint32_t i; 我如何知道gcc是否确实将我视为易变? 它将被声明为是因为没有附近的代码将修改它,并且它的修改可能是由于某些中断。 我不是世界上最差的汇编程序员,但我在电视上播放一个。 有人可以帮我理解它会有什么不同吗? 如果你采取以下愚蠢的代码: #include #include volatile uint32_t i; int main(void) { if (i == 64738) return 0; else return 1; } 将其编译为对象格式并通过objdump反汇编,然后在删除’volatile’后执行相同操作,没有区别(根据diff)。 volatile声明是否太接近于其检查或修改的位置,或者我在声明易失性时应该总是使用某种primefaces类型? 一些优化标志会影响这个吗? 请注意,我的愚蠢样本并不完全符合我的问题,我意识到这一点。 我只是试图找出gcc是否确实将变量视为易失性,所以我正在研究小型转储以试图找到差异。

挥发function

简介 :关键字volatile在应用于C和C ++中的函数声明时会做什么? 细节 : 我看到可以编译一个标记为volatile的函数。 但是,我不确定这会阻止什么编译器优化(如果有的话)。 例如,我创建了以下测试用例: volatile int foo() { return 1; } int main() { int total = 0; int i = 0; for(i = 0; i < 100; i++) { total += foo(); } return total; } 当我使用clang -emit-llvm -S -O3 test.c编译时(gcc也可以工作,但我认为llvm IR更具可读性)我得到: target triple = “x86_64-unknown-linux-gnu” define i32 @foo() #0 […]

在Linux内核中读写primefaces操作实现

最近我看到了primefaces读写的Linux内核实现,并提出了一些问题。 首先是ia64架构的相关代码: typedef struct { int counter; } atomic_t; #define atomic_read(v) (*(volatile int *)&(v)->counter) #define atomic64_read(v) (*(volatile long *)&(v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) #define atomic64_set(v,i) (((v)->counter) = (i)) 对于读取和写入操作,似乎采用直接方法来读取或写入变量。 除非在某处有另一个技巧,否则我不明白这个操作在汇编域中是否具有primefaces性的保证。 我想一个明显的答案是,这样的操作转换为一个程序集操作码,但即便如此,在考虑不同的内存缓存级别(或其他优化)时,如何保证? 在读取宏上,volatile类型用于转换技巧。 任何人都知道这会如何影响这里的primefaces性? (注意,它不用于写操作)

释放(vfree-ing)指向易失性数据的指针

volatile似乎是每个人永无止境的问题。 我以为我知道一切,但后来我遇到了这个: 所以,我在线程之间共享了一块内存,我将其定义如下: volatile type *name; 如果它让你感觉更好,你可以想象type只是一个int 。 这意味着我有一些指针(不易变)到一些易失的数据。 因此,例如在优化方面,编译器可以缓存name的值而不是name[0] 。 我对吗? 所以,现在我正在使用这个指针(它在Linux内核模块中),它告诉我当我传递volatile type *时, vfree需要const void * volatile type * 。 我理解将volatile type *作为type *传递是多么危险,因为在该函数中, name[i]的值可以被高速缓存(作为优化的结果),这是不可取的。 我不明白为什么,但是, vfree希望我将指针发送到非易失性数据。 那里有什么我想念的吗? 或者只是那些写vfree而不考虑这种情况的人? 我假设我只是将我的指针投射到void *不会造成任何伤害,是吗?

易失性和编译器优化

如果关闭编译器优化即(gcc -o0 ….),那么’volatile’关键字没有区别可以吗? 我已经制作了一些示例’C’程序,并且只有在打开编译器优化即((gcc -o1 ….)时才能看到生成的汇编代码中volatile和non-volatile之间的区别。

哪里用volatile?

我读过volatile关键字,但我不知道在什么情况下我应该使用它。 当内存(变量)得到更新并且进程没有意识到这一点? 在什么情况下驱动程序应该使用volatile变量?