String results and the weird stuff

There is an interesting particularity to the Delphi compiler. It relates to Strings and Dynamic Arrays. Consider the following two routines:

function DoSomeThing() : String;
begin
  Result := Result + ' World';
end;

procedure DoSomeThing2(var Result: String);
begin
  Result := Result + ' World';
end;

What is the difference between these two routines? Nothing except the syntax. In both cases Result is actually a var parameter sent to the function. So all the functions that return a string or a dynamic array are treated as procedures that have plus one parameter — the result variable.

Now consider this code:

procedure MyFunction();
var
  X: String;
begin
  X := 'Hello';
  X := DoSomeThing();
end;

You would think that X will become ” World” when in fact the result is “Hello World”. And this is correct if we consider that in fact this call “X := DoSomeThing()” will be translated to “DoSomeThing(X)“.

So the next time you’re writing a function that returns a string or a dynamic array be sure to initialize the Result to an empty string (or a nil for arrays).

One final note: In case of the main begin … end. block this behaviour changes. The compiler will actually allocate another local (invisible) variable that will receive the result and the copy that hidden variable to X so the result will be ” World”. This is probably due to optimizations.