gpt4 book ai didi

c - volatile 指针指向非 volatile 数据

转载 作者:太空宇宙 更新时间:2023-11-04 01:47:57 26 4
gpt4 key购买 nike

我明白声明

int *volatile ptr;

表示指针本身是volatile

int a=10;
int *volatile ptr=&a;

现在 ptra 都在更新。会不会导致访问ptr时返回a的旧值等潜在问题?

阐明可变指针在我的场景中的用例:

  1. 从中断上下文到我正在传递的任务上下文进行通信循环队列(指针数组)的地址,它将从任务上下文中访问。
  2. 此队列中的指针被声明为易变的。
  3. 在队列中的索引 x 处,存在指针 y,它指向变量 a.
  4. 现在如果我写一个新的队列指针(例如指针 z 指向到中断上下文中索引 x 处的变量 b)。
  5. 当我在任务上下文中读取索引 x 时,因为队列被声明为volatile,指针不会被优化。

我的疑问是,因为指针指向的不是易变的,编译器是否有可能针对索引 x 进行了优化,并且在索引 x 处引用指针时,它将指向变量 a 而不是变量 b

最佳答案

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 不会在循环的每一圈都指向相同的地址,但除此之外它可以自由地假定:“啊哈,在阅读 之后ptr 它仍然指向 a 我看到了。它没有更新,我知道它是 10"。理论上,编译器可以自由生成如下伪机器码:

val = *ptr

forever
{
ptr = (update it by reading from memory)
if ptr != previous
val =*ptr

print val
previous = ptr
}

如果编译器可以将先前的值隐藏在 CPU 寄存器等中,那么这种优化可能是有意义的。假设它可以通过这种方式摆脱大量的 printf 开销,那将是一个主要的优化。

所以,不,这不会保护您免受不正确的优化。为此,请改用 volatile int*。或者,如果指针本身也可能发生变化,volatile int* volatile


To communicate from interrupt context to task context I am passing addresses to circular queue (which is array of pointers) which will be accessed from task context.

只有当指针本身被中断更改为指向别处时,这才有意义。同样,这并不意味着指向的数据将被更新。但是当你写“The pointers in this queue are declared volatile.”时,你很好,假设这意味着指针是 volatile* 类型不是 类型* volatile

与这整个问题无关,您还需要防止共享变量的非原子访问。 volatile 没有给出。

关于c - volatile 指针指向非 volatile 数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49753846/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com