Возможно, переменная не была инициализирована. Могу ли я включить это предупреждение для строки?

когда я компилирую этот код

{$WARNINGS ON}
function Test(s: string): string;
var
  t: string;
  d: double;
begin
  if s = '' then begin
    t := 'abc';
    d := 1;
  end;

  Result := t + FloatToStr(d);
end;

Я получаю предупреждение "переменная ' d', возможно, не была инициализирована", но я не получаю такое же предупреждение для переменной 't'. Это кажется непоследовательным. Этот код является лишь простым примером для отображения предупреждений компилятора, но я только что нашел ошибку в моем Живом коде, которая была бы поймана предупреждением во время компиляции для неинициализированных строковых переменных. Могу ли я каким-то образом включить это предупреждение в Delphi 6? Или в более новой версии Дельфи?

2 ответов


нет, для этого нет переключателя. Предупреждение не возникает, поскольку строка является управляемым типом компилятора и всегда инициализируется компилятором.


да :-)

использовать shortstrings или pChars

{$WARNINGS ON}
function Test: String;
var
  p: pChar;
  d: double;
begin
  Result := p + FloatToStr(d);
end;
//This code will give a warning.

серьезно

нет, обычные строки Delphi и короткие строки автоматически инициализируются в " (пустая строка). Shortstrings живут в стеке и не нуждаются в очистке. Другие строки называются "управляемыми" типами и автоматически удаляются, когда они больше не используются с помощью подсчета ссылок.

PChars, хороший новости
pChars лишь указатели. Дельфи делает не управлять ими.
Однако Delphi тут автоматически преобразовать их в строки и наоборот.

pChars плохие новости
Если вы конвертируете pChar в строку Delphi копирует содержимое pChar в строку, и вы по-прежнему несете ответственность за уничтожение pChar.
Также обратите внимание, что это копирование занимает время, и если вы делаете это много замедлит ваш код.

если вы конвертируете string к pChar Delphi даст вам указатель на адрес, в котором живет строка. И !! Delphi перестанет управлять строкой. Вы все еще можете назначить значения строке, но она больше не будет автоматически расти.

From:http://www.marcocantu.com/epascal/English/ch07str.htm

следующий код не будет работать, как ожидалось:

procedure TForm1.Button2Click(Sender: TObject);
var
  S1: String;
begin
  SetLength (S1, 100);
  GetWindowText (Handle, PChar (S1), Length (S1));
  S1 := S1 + ' is the title'; // this won't work
  Button1.Caption := S1;
end;

эта программа компилируется, но когда вы его запускаете, вас ждет сюрприз: заголовок кнопки будет иметь исходный текст заголовка окна без текста постоянной строки, которую вы добавили к нему. Проблема в том, что когда Windows записывает в строку (в пределах GetWindowText вызов API), он не устанавливает длину длинной строки Pascal должным образом. Delphi все еще может использовать эту строку для вывода и может выяснить, когда она заканчивается, ища нулевой Терминатор, но если вы добавляете дополнительные символы после нуль-Терминатор, они будут пропущены.

как мы можем решить эту проблему? Решение состоит в том, чтобы сообщить системе преобразовать строку, возвращаемую GetWindowText API-вызов строки Pascal. Однако, если вы напишете следующий код:

S1 := String (S1);

система проигнорирует его, потому что преобразование типа данных обратно в себя является бесполезной операцией. Чтобы получить правильную длинную строку Pascal, вам нужно преобразовать строку в PChar и позволить Delphi преобразовать ее обратно снова правильно к строке:

S1 := String (PChar (S1));

На самом деле, вы можете пропустить преобразование строк, потому что преобразования PChar в строку в Delphi являются автоматическими. Вот окончательный код:

procedure TForm1.Button3Click(Sender: TObject);
var
  S1: String;
begin
  SetLength (S1, 100);
  GetWindowText (Handle, PChar (S1), Length (S1));
  S1 := String (PChar (S1));
  S1 := S1 + ' is the title';
  Button3.Caption := S1;
end;

альтернативой является сброс длины строки Delphi, используя длину строки PChar, написав:

SetLength (S1, StrLen (PChar (S1)));