你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

关于 volalile陷阱的 分享和更正

[复制链接]
power568 发布时间:2019-10-31 10:33
       今天学习了 volatile 的陷阱,但是有些论坛上的东西都是有一个原版,然后之后的都是大家相互拷贝,拷贝归拷贝,至少得先理解原文的意思吧,或者写完后还是检查以下,虽然掉的东西很少,但是意思就差的很大了。原文这里就不拷贝了,这里说一下其中的错误之处:
   例:到底哪个volatile可能无效
       就在你看过前面几个例子,感觉自己可能已经都弄明白了的时候,请看最后这个例子:

  1.   struct hw_bd {
  2.     ......;
  3.     volatile unsigned char * volatile buffer;
  4.   };
  5.   
  6.   struct hw_bd *bdp;
  7.   
  8.   ......;
  9.   bdp->buffer = ...; ①
  10.   bdp->buffer[i] = ...; ②  (错误的论坛是: bdp->buffer = ...; ② )
复制代码
  
  请问上面标记了①和②的两行代码,哪个是确实在访问volatile对象,而哪个又是undefined的结果?
  
  答案是:②是volatile的,①是undefined。来看本例的数据结构示意图:
  
      (non-volatile)
  bdp -->+-------------+
      |       |
      |  ... ...  |
      |       |
      +-------------+   (volatile)  
      |   buffer  |-->+------------+
      +-------------+  |       |
               |       |
               |       |
               +------------+
               |  buffer |
               +------------+
               |       |
               |       |
               +------------+buffer成员本身是通过一个non-volatile的指针bdp访问的,按照C99标准的定义,这就属于undefined的情况,因此对bdp->buffer的访问编译器不一定能保证是volatile的;
  虽然buffer成员本身可能不是volatile的变量,但是buffer成员是一个指向volatile对象的指针。因此对buffer成员所指对象的访问编译器可以保证是volatile的,所以bdp->buffer是volatile的。
  
最后分享一下原文的链接(我认为的原为,这里仅作知识分享,如涉及到版权等问题,请告知,立即删除):

volatile的陷阱(栢图实验室)
或者
volatile的陷阱(栢图实验室)



好记性不如烂笔头...

11.PNG
13.PNG
441.jpg
收藏 评论4 发布时间:2019-10-31 10:33

举报

4个回答
子曰好人 回答时间:2019-10-31 11:02:07
楼主发的什么东西,表示没看懂,你那两句代码完全一样
power568 回答时间:2019-12-20 17:58:18
子曰好人 发表于 2019-10-31 11:02
楼主发的什么东西,表示没看懂,你那两句代码完全一样

多谢!应该是这样的

  1.   bdp->buffer = ...; ①
  2.   bdp->buffer[i] = ...; ②  (错误的论坛是: bdp->buffer = ...; ② )
复制代码
edmundlee 回答时间:2019-12-21 10:21:42
没验证过, 也没查过C99是否有如此规定, 假若是, 这就有些不合理, 甚至可以说个bug。
结构体的指针因为不是volatile, 所以所有成员就是定义了volatile也没用, 那又何必把成员定义为volatile呢, 就是说要不就整个结构体都是volatile, 要不就都不是volatile。
再者 volatile unsigned char * volatile buffer; 这一句的意思是, 指针是volatile, 指针所指向的内容也是volatile
要知道加volatile本身如非必要就是个额外的损耗。
要是定义另一 unsigned char *buf  = bdp->buffer;
buf[0]=xx;
结果是undefin才是合理的
但因为结构体指针不是volatile而影响到成员就不合理了

点评

volatile肯定会额外增加消耗的。 但是结构体的指针因为不是volatile, 所以所有成员就是定义了volatile也没用,确实有些不合理  发表于 2019-12-27 09:57

所属标签

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版