我理解声明
int *volatile ptr;
表示指针本身是易失性的
int a=10;
int *volatile ptr=&a;
现在正在更新ptr
和a
。它是否会导致在访问a
时返回ptr
的旧值等潜在问题?
在我的场景中澄清易失性指针的用例:
我怀疑是因为指针指向的是非易失性的,编译器是否有可能针对索引x进行优化,并且在索引x处引用指针时,它将指向变量a而不是变量b
答案 0 :(得分:2)
如果ptr和ptr指向的int都由不同的线程或硬件更新,则必须声明ptr如下:
int volatile * volatile ptr=&a;
或者:
volatile int * volatile ptr=&a;
正如@Lundin指出的那样,通常在嵌入式编程中,地址不会改变,所以这就足够了:
volatile int * ptr=&a;
或者:
int volatile * ptr=&a;
答案 1 :(得分:1)
int* volatile
仅表示指针本身为volatile
。指向的数据不是volatile限定的,这意味着以下场景可能会导致优化程序错误:
int a=10;
int* volatile ptr=&a;
int main()
{
for(;;)
{
printf("%d\n", *ptr);
}
}
void some_ISR (void)
{
a = something;
}
编译器小心不要假设ptr
在循环中的每一圈都没有指向同一个地址,但除此之外,可以自由地假设:" aha,在阅读{{1我仍然指着ptr
。它还没有更新,我知道它是10"。从理论上讲,编译器可以自由地生成机器代码,例如伪:
a
如果编译器可以将先前的值保存在CPU寄存器等中,则这种优化可能有意义。假设它可以通过这种方式摆脱大量的printf开销,这将是一个主要的优化。
所以,这并不能保护您免受错误的优化。要实现这一点,请改用val = *ptr
forever
{
ptr = (update it by reading from memory)
if ptr != previous
val =*ptr
print val
previous = ptr
}
。或者,如果指针本身也可能发生变化,volatile int*
。
要从中断上下文传递到任务上下文,我将地址传递给循环队列(指针数组),这些队列将从任务上下文中访问。
只有当指针本身被中断改变为指向别处时才有意义。同样,它并不意味着将更新指向的数据。但是当你编写"这个队列中的指针被声明为volatile。",你很好,假设这意味着指针是volatile int* volatile
而不是 {{1 }}
与整个问题无关,您还需要防止共享变量的非原子访问。 volatile* type
没有给出这一点。
答案 2 :(得分:0)
a
通过volatile
指针的任何使用都会使取消引用也变得不稳定(因为指针的值没有被缓存,所以必须完全取消引用)但是,更好的是制作两者都是不可缓存的,所以可能的实现方式是:
volatile int a;
volatile int * volatile ptr = &a;
请三思而后行,因为您尚未将a
声明为volatile
,如果您已完成此操作,则会收到警告:
#include <stdio.h>
int main()
{
volatile int a;
int * volatile ptr = &a;
}
和输出
$ make pru
pru.c:5:17: warning: initializing 'int *volatile' with an expression of type 'volatile int *' discards qualifiers
[-Wincompatible-pointer-types-discards-qualifiers]
int * volatile ptr = &a;
^ ~~
1 warning generated.
从警告中可以看出,丢弃的限定符引用了指向的值。如果ptr
被声明为非volatile
,则会发出相同的警告:
#include <stdio.h>
int main()
{
volatile int a;
int * ptr = &a;
}
和
$ make pru2
cc -O -pipe pru.c -o pru
pru.c:5:8: warning: initializing 'int *' with an expression of type 'volatile int *' discards qualifiers
[-Wincompatible-pointer-types-discards-qualifiers]
int * ptr = &a;
^ ~~
1 warning generated.