to000000.pp 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. Program UnsureOptsFail;
  2. {This program shows how unsure optimizations can cause wrong code if you
  3. program Silly Things (TM)
  4. The principle is always the same:
  5. you have a normal variable (local or global) and a pointer to it in one way
  6. or another (be it a normal pointer or a var parameter).
  7. a) you first cause the value from the memeory location to be loaded in a
  8. register (e.g. by using the normal variable as an array index)
  9. b) next you assign a new value to the memory location (e.g. through the
  10. pointer)
  11. c) finally, you compare the two values
  12. Of course you can also use the pointer as an array index and assign a new
  13. value to the normal variuable, that doesn't change anything).
  14. The problem is that the value of the first load is still in a register, so
  15. it isn't loaded from memory again, so you compare the old value with the
  16. new one.
  17. Note: this code doesn4t function correctly only when compiled with uncertain
  18. optimizations on. All other forms of optimization are completely safe.
  19. }
  20. var l: longint;
  21. p: ^longint;
  22. a: Array[1..10] of byte;
  23. Procedure ChangeIt(var t: longint);
  24. {The same principle as in the main program, only here we have a var parameter
  25. instead of a "normal" pointer. If l is passed to this procedure, it doesn't
  26. function right.}
  27. Begin
  28. t := 1;
  29. If t = l Then {t gets loaded in a register (eax)}
  30. Begin
  31. l := 2;
  32. If t <> l then
  33. Writeln('She can''t take any more or she''ll blow, captain!');
  34. End;
  35. End;
  36. begin
  37. p := @l; {p points to l}
  38. l := 1;
  39. a[p^] := 2; {load p^ in a register (eax in this case)}
  40. l := 2; {change the value of l}
  41. If p^ <> l
  42. Then Writeln('Houston, we have a problem!');
  43. ChangeIt(l);
  44. End.