class AtomicityExample { decimal _value; void SetValue(decimal value) {_value = value;} decimal GetValue() {return _value;} }If the code is executed by many threads, the returned value of GetValue method may be not a value that was set by a SetValue.
What is even less know is that the order of the operations in C# may change, due to .net optimization. Consider following code:
class OrderExample { decimal d1; volatile decimal d2; decimal d3; void Assign(){ d1 = 1; d2 = 2; d3 = 3; } }The assignment in a code above can happen in following ways:
d1 = 1; d2 = 2; d3 = 3;or
d1 = 1; d3 = 3; d2 = 2;or
d3 = 3; d1 = 1; d2 = 2;In other words volatile variable can be assigned only after d1 was assigned, but when exactly depends on a compiler. Be aware that majority of programmers don't even use volatile keyword, and without volatile keyword reads/writes of variables above can happen in any order. And it matters, because I've seen so many times a code that looked like:
class FalseSecurityExample { decimal d1; bool assigned; void Assign(){ d1 = 1; assigned = true; } decimal Calculate(){ if(assigned){ return d1; } } }It means that in an example above d1 may not be set before it is returned, and if you add to a consideration fact that decimal is not atomic, you can expect anything to be returned by this code.
When I ask people why do they write such code, and if they are aware of issues that are illustrated above, usually they answer, that we are not writing a project for NASA, or anything like that so bug off. Interesting.
No comments:
Post a Comment