当前位置: 首页 > 知识库问答 >
问题:

C++编译器可以消除不被读取的易失性本地变量吗

胡新
2023-03-14
int f() {
  volatile int c;
  c=34;
  return abc();
}
int f() {
  volatile int c;
  memset((void*)&c,34, 1); 
  return abc();
}

那么按照C++标准,编译器能消除易变的int C吗?我想VC++中可能存在一些与内部函数如何优化volatile变量有关的不一致行为。

共有1个答案

蒋飞捷
2023-03-14

那么按照C++标准,编译器能消除易变的int C吗?

不,volatile限定对象用于从硬件读取或写入硬件,并且分配volatile对象的副作用是可以观察到的。

因此,根据所谓的“好像”规则对优化设置的约束,不允许符合条件的实现优化c。C++11标准第1.9/1段正式引入了“好像”规则:

-对易失性对象的访问严格按照抽象机器的规则进行评估。

-在程序终止时,写入文件的所有数据应与根据抽象语义执行程序可能产生的结果之一相同。

-交互设备的输入和输出动态应以这样一种方式发生,即在程序等待输入之前,提示输出实际上已交付。构成交互设备的是实现定义的。

 类似资料:
  • 我最近一直在尝试重新熟悉多线程,并找到了这篇论文。其中一个例子说在使用类似这样的代码时要小心: 声明: 是作者写错了,还是我漏掉了什么?

  • 我已经阅读了许多相互矛盾的信息(msdn,SO等),关于易失性和VoletleRead(ReadAcquireFence)。 我理解这些限制的内存访问重新排序含义——我仍然完全搞不清楚的是新鲜度保证——这对我来说非常重要。 msdn doc用于挥发性提及: (…)这样可以确保字段中始终存在最新的值。 挥发性字段的msdn文档提到: 对易失性字段的读取称为易失性读取。易失性读取具有“获取语义”;也就

  • 官方记录说 写入易失性字段与监视器释放具有相同的记忆效果,从易失性字段读取与监视器获取具有相同的记忆效果。 和 有效地,挥发性的语义学得到了实质性的加强,几乎达到了同步的水平。为了可见性的目的,挥发性字段的每次读取或写入都像“半”次同步。 从这里开始。 这是否意味着,对volatile变量的任何写入都会使执行线程将其缓存刷新到主存中,而每次从volatile字段读取都会使线程从主存重新读取其变量?

  • 所有的中断函数都能正常工作,但是过程函数却让我很生气。 我会感激任何我没注意的把戏。

  • 谢谢,伊利亚

  • C标准允许根据缺陷报告1688(已于2013年9月解决)使用变量: 这种组合是有意允许的,在某些情况下可以用来强制常量初始化。 看起来,其目的是只允许,这在C 20之前是不可用的。 在某些情况下,当前的编译器在处理方面仍然存在分歧。例如,此程序通过另一个变量初始化一个这样的变量: 它在GCC和MSVC中被接受,但Clang抱怨: 在线演示:https://gcc.godbolt.org/z/43e