Forum > General

SetLength and compiler hints

(1/2) > >>

Grahame Grieve:
I've just been caught out by an uninitialised variable. I didn't get any hint for it - I'll get to that later. So I've turned all uninitialised variable hints back on, and this code generates a hint:

function StringToShortString(const S: String) : ShortString;
var
  i : integer;
begin
  SetLength(result, min(s.Length, 255));
  for i := 1 to length(result) do
    result := AnsiChar(s);
end; 

I have 1000s of these things - pretty much whereever I use SetLength, I'm going to get a warning. But why? I am initialising the variable...

PascalDragon:
That is the case due to the way types like ShortString, AnsiString or dynamic arrays are handled as result types. They are passed as a hidden var parameter, so in fact your function declaration internally looks like this:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---procedure StringToShortString(const S: String; var Result: ShortString);
Now depending on the code you have it can be that what the compiler passes in as Result contains valid data, thus while you might set the length correctly you might still have “garbage” in there (in your case you set each character, so that doesn't matter here).

For example:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---program tresult; {$mode objfpc} function Test1: ShortString;begin  Result := 'Test';end; function Test2: ShortString;begin  Writeln(Result);end; procedure Test;var  ss: ShortString;begin  ss := Test1;  ss := Test2;end; begin  Test;end.
This will print “Test”. So safest in those cases is to do a Result := ''; before changing the length.

And before you ask: no, this won't be changed and yes, that can happen in Delphi as well.

creaothceann:
If you're sure that it'll always be a ShortString then you can also set the length via Result[0].


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---function StringToShortstring(const s : string) : Shortstring;var        i : integer;begin        i := min(s.Length, 255);        Result[0] := AnsiChar(i);        for i := 1 to i do  Result[i] := AnsiChar(s[i]);        // alternative: Result := Copy(s, 1, min(s.Length, 255));end;  

Grahame Grieve:
what about for dynamic arrays, where the same issue arises - I can't set them to ''

Bart:
Set them to nil.

Bart

Navigation

[0] Message Index

[#] Next page

Go to full version