|
@@ -0,0 +1,65 @@
|
|
|
+program tw40315;
|
|
|
+//This program compiles and runs in Delphi and in FPC. (at least should run in FPC)
|
|
|
+//It is intentionally designed this way.
|
|
|
+//It compiles without errors or warnings in Delphi and delivers the expected result.
|
|
|
+
|
|
|
+{$ifdef FPC}
|
|
|
+ {$mode objfpc}{$H+}
|
|
|
+ {$modeswitch functionreferences}
|
|
|
+ {$modeswitch anonymousfunctions}
|
|
|
+ // {$warn 5036 off}// "Warning: (5036) Local variable "$Capturer" does not seem to be initialized"
|
|
|
+{$endif}
|
|
|
+uses
|
|
|
+ {$IFDEF UNIX}
|
|
|
+ //cthreads,
|
|
|
+ {$ENDIF}
|
|
|
+ Classes,Sysutils { you can add units after this };
|
|
|
+
|
|
|
+type TfuncS = reference to function:String;
|
|
|
+ TfuncF = reference to function(s:String):TfuncS;
|
|
|
+var f_inner: TfuncS;
|
|
|
+ f_outer: TfuncF;
|
|
|
+
|
|
|
+procedure caller;
|
|
|
+begin
|
|
|
+ f_inner();
|
|
|
+end;
|
|
|
+
|
|
|
+procedure main;
|
|
|
+
|
|
|
+var str: String;
|
|
|
+ // f_outer: TfuncF; // <---- doesnt compile in FPC when this is uncommented, but compiles and runs ok in Delphi
|
|
|
+
|
|
|
+begin
|
|
|
+
|
|
|
+ str := 'Hello World!';
|
|
|
+
|
|
|
+ f_outer := function(s:String):TfuncS //This captures local and persistent copy of "str"
|
|
|
+ begin
|
|
|
+ Result := function:String // <---- Access violation here, when Line "Result:=s" is commented out and when it is compiled.
|
|
|
+ begin
|
|
|
+ Result := s; // <---- project1.lpr(37,9) Error: Internal error 2011010304
|
|
|
+ // if the line is commented out it compiles, but gives access violation at runtime
|
|
|
+
|
|
|
+ Writeln(s);
|
|
|
+ end;
|
|
|
+ Writeln('Outer function was called');
|
|
|
+ end;
|
|
|
+ f_inner := f_outer(str); //This instantiates the outer function and f_inner and captures their local context.
|
|
|
+
|
|
|
+ SetLength(str,0); //Erase the string content
|
|
|
+
|
|
|
+ Writeln('now calling f_inner');
|
|
|
+ caller(); //This line prints the string s="Hello World!", which was captured by the outer function.
|
|
|
+ //f_inner will be called from an external context, this is just for test and demonstration
|
|
|
+end;
|
|
|
+
|
|
|
+begin
|
|
|
+ main;
|
|
|
+ Writeln('Now the context of "main()" is lost. Can we still print the string "str"?');
|
|
|
+ //if f_inner()='Hello World!' then writeln('Yes! :-)') else writeln ('No! :-(');
|
|
|
+ if f_inner()<>'Hello World!' then
|
|
|
+ Halt(1);
|
|
|
+
|
|
|
+ //readln;
|
|
|
+end.
|