gpt4 book ai didi

c - 在 C 中重新排序对多个 volatile 变量的访问

转载 作者:太空宇宙 更新时间:2023-11-04 04:16:12 27 4
gpt4 key购买 nike

在这个例子中:

volatile uint32_t * pOne = 0xDEADBEEF;
volatile uint32_t * pTwo = 0x0BADC0DE;

void same(void)
{
uint32_t tmp;

tmp = *pOne; // A
*pOne = 0; // B
*pOne = tmp; // C
}

void different(void)
{
uint32_t tmp;

tmp = *pOne;
*pOne = 0; // E
*pTwo = 0; // F
*pOne = tmp;
}

据我所知,C99 编译器不允许对函数 中的行 ABC 重新排序same(),因为它们都引用同一个 volatile 对象。
但是 different() 函数中的 EF 行呢?它们与不同的 volatile 对象交互。

  1. 是否允许 C99 编译器对 EF 行重新排序?

我无法在标准本身中找到答案,因为第 5.1.2.3 节让我有点困惑。所以如果你能解释一下,我会很高兴。

我知道这只涉及编译器的重新排序,不会影响处理器的任何重新排序。

  1. 那么是否有一个标准库(如果已实现)提供内存屏障?

  2. 目前我坚持使用 C99,但出于好奇:C11 有什么变化吗?

最佳答案

关于 volatile 对象的语义,允许实现相当大的自由裁量权。程序的可观察行为必须与以指定顺序执行的所有 volatile 对象的所有操作一致,但实现具有执行几乎任何不影响程序可观察行为的任何事情的全面许可。实现也有相当广泛的权限来指定——在“实现定义的行为”领域内——volatile 限定访问的哪些方面是和不是“可观察的”。

不适合嵌入式编程的符合规范的实现可以指定 volatile 限定的访问将以奇怪和任意的方式运行,这将使其无法用于此类目的。在大多数平台上,应该非常清楚旨在允许在不使用编译器特定指令的情况下进行嵌入式编程的质量实现应该如何处理 volatile 限定的访问,以及用于此类用途的高质量实现即使标准不要求他们这样做,也应该以这种方式处理它们。不幸的是,一些编译器作者将他们的语义限制在标准明确要求的范围内,而不是扩展他们的语义以匹配底层平台(例如,当针对 volatile 访问可能表现得像子程序调用的平台时,不要对 volatile 访问中的任何操作重新排序,除非它可以通过对未知函数的调用重新排序)。虽然 icc 似乎以这种方式处理 volatile 限定的写入,但像 gccclang 这样的编译器却不是专为适合启用优化的嵌入式系统使用而设计,只有在禁用大多数优化时才会这样做。

关于c - 在 C 中重新排序对多个 volatile 变量的访问,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52146098/

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