|
今天学习了 volatile 的陷阱,但是有些论坛上的东西都是有一个原版,然后之后的都是大家相互拷贝,拷贝归拷贝,至少得先理解原文的意思吧,或者写完后还是检查以下,虽然掉的东西很少,但是意思就差的很大了。原文这里就不拷贝了,这里说一下其中的错误之处:8 j' B+ `0 E, j; E& Q! ?& T$ @ 例:到底哪个volatile可能无效 就在你看过前面几个例子,感觉自己可能已经都弄明白了的时候,请看最后这个例子:
请问上面标记了①和②的两行代码,哪个是确实在访问volatile对象,而哪个又是undefined的结果? - R8 C1 Z$ i/ g: @, ^ 答案是:②是volatile的,①是undefined。来看本例的数据结构示意图: (non-volatile), a; ]6 m$ W5 D! O1 k( F bdp -->+-------------+ | | | ... ... | | | +-------------+ (volatile) 7 V2 d) f- R. N3 w4 C | buffer |-->+------------+- d. r1 M; ?$ s% r) ^2 j- c +-------------+ | |+ M4 i/ `; H0 V1 E y" a) O | | | | +------------+ | buffer | +------------+ | | | | +------------+buffer成员本身是通过一个non-volatile的指针bdp访问的,按照C99标准的定义,这就属于undefined的情况,因此对bdp->buffer的访问编译器不一定能保证是volatile的; 虽然buffer成员本身可能不是volatile的变量,但是buffer成员是一个指向volatile对象的指针。因此对buffer成员所指对象的访问编译器可以保证是volatile的,所以bdp->buffer是volatile的。 ( q- h- d' i3 ~ 最后分享一下原文的链接(我认为的原为,这里仅作知识分享,如涉及到版权等问题,请告知,立即删除): F& R9 b8 f$ r" f$ t0 \ volatile的陷阱(栢图实验室)- w5 C! r* l. W, ~; E' g 或者5 N/ p2 W: G! F" s- v; g volatile的陷阱(栢图实验室) ' t3 \/ U! H3 F# k+ U1 j * y/ G# N9 h: o# u5 ~ 好记性不如烂笔头... + e5 w) M. p+ u3 i |
微信公众号
手机版
多谢!应该是这样的8 _8 v+ ]2 i3 ]
结构体的指针因为不是volatile, 所以所有成员就是定义了volatile也没用, 那又何必把成员定义为volatile呢, 就是说要不就整个结构体都是volatile, 要不就都不是volatile。0 N2 s" f; P' D. H& }! O
再者 volatile unsigned char * volatile buffer; 这一句的意思是, 指针是volatile, 指针所指向的内容也是volatile& m( o& q) G3 h1 E7 y& b
要知道加volatile本身如非必要就是个额外的损耗。
要是定义另一 unsigned char *buf = bdp->buffer;
buf[0]=xx;8 P) d1 F9 ^! ]- A, I$ I8 @0 W
结果是undefin才是合理的* G- x4 s3 P( C7 z
但因为结构体指针不是volatile而影响到成员就不合理了
点评