这将是一个漫长的过程,关于它的上下文并提供尽可能多的信息,我必须通过各种链接和引用来蜿蜒 - 这通常是我们进入C/C++标准兔子洞后的唯一方法.如果您对此帖有更好的引用或任何其他改进,请告诉我.但是要事先总结,你可以责怪@ zwol发布这个;-)并且目的是从两个命题中找到真相:
volatile *或volatile &必须引用最初声明的对象volatile才能具有volatile语义?volatile通过volatile指针/引用访问非限定对象足够/应该使所述访问行为就像声明对象一样volatile?无论哪种方式,如果(看起来)措辞与意图相比有些含糊不清 - 我们能否在标准本身中明确说明?
这些相互排斥的解释中的第一个更常见,而且并非完全没有依据.但是,我希望表明对第二个问题有很大的"合理怀疑" - 尤其是当我们回到基本原理和WG论文中的一些先前段落时.
volatile昨天流行的问题是"挥发性"这个波动的定义,还是GCC有一些标准的合规性问题?通过假设一个volatile引用会赋予volatile非volatile指示物行为- 但发现它没有,或者在不同程度上以不可预测的方式发生行为而产生.
接受的答案最初得出结论,只有声明的指称类型才重要.这个和大多数评论似乎都同意我们所熟知的等效原则在起作用const:volatile如果引用与引用对象具有相同的cv -qualification,则行为将仅(或根本定义):
该段落中的关键词是对象.
volatile sig_atomic_t flag;是一个易变的对象.*(volatile char *)foo仅仅是通过挥发性合格左值的访问,标准不要求具有任何特殊效果.- zwol
这种解释似乎得到了广泛的解释,正如对这个相似但希望不重复的问题的回答所示:指向易失性指向非易失性对象的行为要求但即使在那里也存在不确定性:答案是'不',然后说'也许'!无论如何......让我们检查一下标准,看看'不是'的基础.
C11,N1548,§6.7.3:虽然很明显它是UB来访问一个定义 的对象volatile或const …
这是受到这个问题/答案以及随后在评论中讨论的启发:"易变"这个定义是不稳定的,还是GCC有一些标准的合规性问题?.基于其他人以及我对应该发生的事情的解释,如评论中所讨论的,我已将其提交给GCC Bugzilla:https://gcc.gnu.org/bugzilla/show_bug.cgi ? id = 71793 其他相关回复仍然存在欢迎.
此外,该线程引发了这个问题:通过易失性引用/指针访问声明的非易失性对象是否会在所述访问时赋予易失性规则?
我知道volatile这不是大多数人认为的,而且是实施定义的毒蛇巢.我当然不想在任何实际代码中使用以下结构.也就是说,我对这些例子中发生的事情感到非常困惑,所以我真的很感激任何解释.
我的猜测是,这是由于对标准的高度细微差别的解释,或者(更可能的是)对于所使用的优化器的角落情况.无论哪种方式,虽然更具学术性而非实际性,但我希望这对于分析是有价值的,特别是考虑到通常误解的volatile情况.一些更多的数据点 - 或者更有可能是针对它的点 - 必须是好的.
鉴于此代码:
#include <cstddef>
void f(void *const p, std::size_t n)
{
unsigned char *y = static_cast<unsigned char *>(p);
volatile unsigned char const x = 42;
// N.B. Yeah, const is weird, but it doesn't change anything
while (n--) {
*y++ = x;
}
}
void g(void *const p, std::size_t n, volatile unsigned char …Run Code Online (Sandbox Code Playgroud)