On Thu, Aug 23, 2012 at 1:18 AM, David Brown <david.br...@hesbynett.no> wrote: > (I've put this back on the mailing list - I assume you meant to do that, and > just pressed the wrong "reply" button.)
Oops. > I can see your point, but I am not convinced it is correct. You are talking > about a very grey area of the C specs here - "volatile" is simply not well > enough specified in the C standards. There was a well-publicised paper > recently which looked at code generated by a variety of compilers for > different volatile constructs, which concluded that most (or all, I think) > compilers got things wrong in some circumstances. The obvious conclusion to > take from that is that you must keep volatile code simple. If not, then > either /you/ will get it wrong, or the /compiler/ will get it wrong. And > even if both are right, the hardware can still be a limitation. This very > example shows the problems caused by complex volatile code - you agree the > compiler's output is correct based on the source code, yet it does not do > what you want it to do or think it should do. > > So by the coding rules I use, the code you wrote is wrong - regardless of > what the compiler generates, or even whether or not it works. Ah, that makes sense. In other words, proceed with caution - here be dragons. You rules basically describe the "safe" ways to use volatile variables, and anything else might mean trouble. > Then separate the two operations into two lines of code: > > uint8_t newBits = (state >> 1) & DIRTY_FLAG; > state |= newBits; > > That makes the code much clearer - and it explicitly shows that the two > operations can be split up. Otherwise you've got a maintenance problem for > the future when a new programmer tries to figure out what works or does not > work. > > And maybe you'll be lucky and the "|=" will be implemented atomically with > that code. Simple statements are critical to getting volatile right, and it > gives the compiler the best chance. There are no guarantees, however. I tried this, and the emitted code stays the same. The data-dependency graph hasn't really changed, so it makes sense that the output wouldn't change either. > Another option is a single inline assembly call for the "|=" if the above > code split does not help. I've had to do this in a few places, like when I need to atomically update a hardware flag. The rest of the code seems to work with your rules, although I have to shuffle quite a bit of stuff around to accomplish that. Thanks for your suggestions. -William ------------------------------------------------------------------------------ Live Security Virtual Conference Exclusive live event will cover all the ways today's security and threat landscape has changed and how IT managers can respond. Discussions will include endpoint security, mobile security and the latest in malware threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/ _______________________________________________ Mspgcc-users mailing list Mspgcc-users@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/mspgcc-users