mirror of
				https://gitlab.com/freepascal.org/fpc/source.git
				synced 2025-10-31 11:53:42 +01:00 
			
		
		
		
	+ to000000.pp
This commit is contained in:
		
							parent
							
								
									52f38ed4a5
								
							
						
					
					
						commit
						ccd97bbec9
					
				| @ -28,3 +28,5 @@ ts010015.pp       tests typed files. | ||||
| ts10100.pp        tests for delphi object model | ||||
| - | ||||
| ts101xx.pp | ||||
| 
 | ||||
| to000000          shows when uncertain optimizations can cause wrong code | ||||
|  | ||||
							
								
								
									
										53
									
								
								tests/to000000.pp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										53
									
								
								tests/to000000.pp
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,53 @@ | ||||
| Program UnsureOptsFail; | ||||
| {This program shows how unsure optimizations can cause wrong code if you | ||||
|  program Silly Things (TM) | ||||
| 
 | ||||
|  The principle is always the same: | ||||
| 
 | ||||
|  you have a normal variable (local or global) and a pointer to it in one way | ||||
|  or another (be it a normal pointer or a var parameter). | ||||
| 
 | ||||
|  a) you first cause the value from the memeory location to be loaded in a | ||||
|     register (e.g. by using the normal variable as an array index) | ||||
|  b) next you assign a new value to the memory location (e.g. through the | ||||
|     pointer) | ||||
|  c) finally, you compare the two values | ||||
| 
 | ||||
|  Of course you can also use the pointer as an array index and assign a new | ||||
|  value to the normal variuable, that doesn't change anything). | ||||
| 
 | ||||
|  The problem is that the value of the first load is still in a register, so | ||||
|  it isn't loaded from memory again, so you compare the old value with the | ||||
|  new one. | ||||
| 
 | ||||
|  Note: this code doesn4t function correctly only when compiled with uncertain | ||||
|  optimizations on. All other forms of optimization are completely safe. | ||||
|  } | ||||
| 
 | ||||
| var l: longint; | ||||
|     p: ^longint; | ||||
|     a: Array[1..10] of byte; | ||||
| 
 | ||||
| Procedure ChangeIt(var t: longint); | ||||
| {The same principle as in the main program, only here we have a var parameter | ||||
|  instead of a "normal" pointer. If l is passed to this procedure, it doesn't | ||||
|  function right.} | ||||
| Begin | ||||
|   t := 1; | ||||
|   If t = l Then   {t gets loaded in a register (eax)} | ||||
|     Begin | ||||
|       l := 2; | ||||
|       If t <> l then | ||||
|         Writeln('She can''t take any more or she''ll blow, captain!'); | ||||
|     End; | ||||
| End; | ||||
| 
 | ||||
| begin | ||||
|   p := @l;     {p points to l} | ||||
|   l := 1; | ||||
|   a[p^] := 2;  {load p^ in a register (eax in this case)} | ||||
|   l := 2;      {change the value of l} | ||||
|   If p^ <> l | ||||
|     Then Writeln('Houston, we have a problem!'); | ||||
|   ChangeIt(l); | ||||
| End. | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jonas Maebe
						Jonas Maebe