Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2006.10.08;
Скачать: CL | DM;

Вниз

Почему компилятор предупреждает?   Найти похожие ветки 

 
Vovan#1   (2006-09-14 22:53) [0]

Функция должна возвращать трёхмерный массив, а точнее - массив двумерных массивов, каждое из звеньев выделено в тип. Компилятор ругается на то, что значение ф-ии может быть неопределено и это даже при том, что я поставил в самое начало следующий код:


 SetLength(Result, 3);
 for i := Low(Result) to High(Result) do
  begin
   SetLength(Result[i], 1, 1);
   Result[i][0,0] := 0;
  end;


Почему так?


 
Eraser ©   (2006-09-14 23:03) [1]

> [0] Vovan#1   (14.09.06 22:53)

компилятор не на столько умен, чтобы ещё заглядывать какие там операнды в операторе цикла, так что избавиться от предупреждения можно добавив строку Result[i][0,0] := 0; сразу после SetLength(3, 3);

кстати не понял, почему

> SetLength(Result, 3);

Result ведь в данном случае действительно ещё не опеределен!


 
Vovan#1   (2006-09-14 23:14) [2]

>Eraser ©   (14.09.06 23:03) [1]

Если честно, то не внял ни первому, ни второму. Можешь поставить что-надо в код, чтоб наглядно было? И в чём проблема с SetLength(Result, 3)?

Суть в том, что всё работает, но компилятор нервирует.


 
Anatoly Podgoretsky ©   (2006-09-14 23:16) [3]

Кстати, а почему бы не написать сразу SetLength(Result, 3, 1, 1);


 
Eraser ©   (2006-09-14 23:19) [4]

> [2] Vovan#1   (14.09.06 23:14)


> И в чём проблема с SetLength(Result, 3)?

какой тип возращаемый функцией?
допустим если одномерный массив, то все правильно, но все равно значение не определено.
как лечить - написал в [1].


 
Vovan#1   (2006-09-14 23:29) [5]

Возвращает тип
 TSomeType = array of T2DArray;
 T2DArray = array of array of Integer;

Написал в начале:

SetLength(Result, 1, 1, 1);
Result[0, 0, 0] := 0;

Всё равно ругается!

>Anatoly Podgoretsky ©   (14.09.06 23:16) [3]

Я хочу именно сохранить записать SetLength(Result, 3), потому что каждый двумерный массив будет заполнять другая функция, которая его размер и установит. То, что идёт цикл заполнения сразу - это я сейчас написал для примера.


 
Eraser ©   (2006-09-14 23:42) [6]

> [5] Vovan#1   (14.09.06 23:29)


> Компилятор ругается на то, что значение ф-ии может быть
> неопределено и это даже при том, что я поставил в самое
> начало следующий код:
>
>
> SetLength(Result, 3);
> for i := Low(Result) to High(Result) do
>  begin
>   SetLength(Result[i], 1, 1);
>   Result[i][0,0] := 0;
>  end;

type
 T2DArray = array of array of Integer;
 TSomeType = array of T2DArray;
...
function SomeFn: TSomeType;
var
 i: Integer;
begin
 SetLength(Result, 3);
 for i := Low(Result) to High(Result) do
 begin
   SetLength(Result[i], 1, 1);
   Result[i][0,0] := 0;
 end;
end;

компилятор не ругается.


 
Vovan#1   (2006-09-14 23:50) [7]

В твоём примере если удалить тело функции, то тоже ругаться не будет. Я уже вытался локализовать ошибку. Но не получилось.

Мой код у меня ругается. Двойной щелчок по сообщению [Warning] xxx.pas(479): W1035 Return value of function "xxx" might be undefined выводит на SetLength(Result, 3). Чего-то тут не то.


 
Eraser ©   (2006-09-14 23:56) [8]

> [7] Vovan#1   (14.09.06 23:50)
> В твоём примере если удалить тело функции, то тоже ругаться
> не будет.

в моем примере, как он есть - не ругается.


 
Джо ©   (2006-09-14 23:59) [9]

Мы имеем дело со случаем, известным под названием "Партизан на допросе в Гестапо".


 
Anatoly Podgoretsky ©   (2006-09-15 00:35) [10]

Vovan#1   (14.09.06 23:29) [5]
Это не для предупреждения сообщения, а оптимизация, зачем делать выделение в цикле.


 
Mike Petrichenko   (2006-09-15 01:42) [11]

Перед SetLength(Result, 3)
пиши Result := nil;
Ругаться не будет :)
Вопрос, что это даст?


 
Anatoly Podgoretsky ©   (2006-09-15 13:19) [12]

Может ругаться и не будет, но все равно значение ф-ии может быть неопределено.


 
Vovan#1   (2006-09-15 18:42) [13]

В общем, сегодня я, обвинённый в невыдаче кода, скопировал проект и стал всё удалять, оставляя эту функцию и следя за варнингами компилятора. SetLength как была, так и осталась. В результате дошло до того, что если удаляешь то, про что компилятор пишет - assigned value is never used, то исчезает варнинг про неопределённость результата. Если удаляешь неиспользуемую переменную - тоже исчезает варнинг. Если упрощаешь выражение, значение которого не используется - пропадает варнинг.

Вот вам код:

unit Unit1;

interface

uses
 Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
 Dialogs;

type
 TForm1 = class(TForm)
 private
   { Private declarations }
 public
   { Public declarations }
 end;

var
 Form1: TForm1;

 type
 TPixelArray = array of array of Integer;
 Tsomearray = array of TPixelArray;

 Tsomeset = record
   FullBlack: TColor;
   LettersCount: Integer;
  Similarity: Integer;
  RectWidth: Integer;
  RectHeight: Integer;
  gogol: Boolean;
  propolis: Integer;
  propolis2: Integer;
 end;

function somefunct(var B: TPixelArray; S: Tsomeset): Tsomearray;

implementation

{$R *.dfm}

type
 TLetterColors = array [1..3] of TColor;

type
 PColorFreq = ^TColorFreq;
 TColorFreq = record
   Color: TColor;
   Freq: Integer;
 end;

function somefunct(var B: TPixelArray; S: Tsomeset): Tsomearray;
var
 FL: TList;
 x, y, n, m, i, k: Integer;
 x1, y1: Integer;
 H1, H2, S1, S2, L1, L2: Word;
 W, H: Integer;
 Temp: TPixelArray;
 LC: TLetterColors;
 IsInside: Boolean;
 InsideStart: Integer;
 InsideEnd: Integer;
 DoneLetter: Boolean;
 CI: PColorFreq;
 C: Tcolor;
begin
 W := Length(B);
 H := Length(B[0]);

 SetLength(Result, 3);

 for i := 1 to 3 do
  begin
  x := (W - S.RectWidth * 3) div 4 * i     // zakommentitui eto!
  + (S.RectWidth * (i - 2));
   y := 12;

    for y := 0 to H-1 do
     for x := 1 to W-2 do
       If (Result[i-1][x,y] = S.FullBlack) and
          (Result[i-1][x-1,y] <> S.FullBlack) and
          (Result[i-1][x+1,y] <> S.FullBlack) then
           Result[i-1][x,y] := Result[i-1][x-1,y];
    for x := 0 to W-1 do
     for y := 1 to H-1 do
       If (Result[i-1][x,y] = S.FullBlack) and
          (Result[i-1][x,y-1] <> S.FullBlack) and
          (Result[i-1][x,y+1] <> S.FullBlack) then
           Result[i-1][x,y] := Result[i-1][x,y-1];

   if S.gogol then
     begin
      for n := 1 to 2 do
       begin
        IsInside := False;
        InsideStart := 0;
        for y := 0 to H-1 do
          for x := 0 to W-1 do
           begin
             If (not IsInside) and (Result[i-1][x,y] <> S.FullBlack) then
              begin
               IsInside := True;
               InsideStart := x;
             end;
            If (IsInside) and (Result[i-1][x,y] = S.FullBlack) then
             begin
               IsInside := False;
               InsideEnd := x;
               If (InsideEnd-InsideStart) < S.propolis then
                begin
                  for k := InsideStart to InsideEnd do
                   Result[i-1][k,y] := S.FullBlack;
                end;
             end;
           end;
        IsInside := False;
        InsideStart := 0;
        for x := 0 to W-1 do
          for y := 0 to H-1 do
           begin
            If (not IsInside) and (Result[i-1][x,y] <> S.FullBlack) then
             begin
              IsInside := True;
              InsideStart := y;
             end;
            If (IsInside) and (Result[i-1][x,y] = S.FullBlack) then
             begin
               IsInside := False;
               InsideEnd := y;
               If (InsideEnd-InsideStart) < S.propolis2 then
                begin
                  for k := InsideStart to InsideEnd do
                   Result[i-1][x,k] := S.FullBlack;
                end;
             end;
          end;
        end;
      for k := 1 to 2 do
       begin
         for y := 0 to H-1 do
           for x := 1 to W-2 do
           If (Result[i-1][x,y] <> S.FullBlack) and
                (Result[i-1][x-1,y] = S.FullBlack) and
                (Result[i-1][x+1,y] = S.FullBlack) then
                 Result[i-1][x,y] := S.FullBlack;
         for x := 0 to W-1 do
           for y := 1 to H-1 do
           If (Result[i-1][x,y] <> S.FullBlack) and
                (Result[i-1][x,y-1] = S.FullBlack) and
                (Result[i-1][x,y+1] = S.FullBlack) then
                 Result[i-1][x,y] := S.FullBlack;
       end;
     end;
  end;
end;

end.


Или скачайте его:

И объясните мне, почему если закомментировать обозначенную строчку - исчезает варнинг? Почему он вообще есть? И почему про переменную DoneLetter не пишет, что она задекларированна, но не используется, а про другие - пишет. Использую Borland Delphi 2005.


 
Vovan#1   (2006-09-15 18:43) [14]

Ссылку забыл
http://www.speedyshare.com/309606196.html
9 килобайт.


 
Плохиш ©   (2006-09-15 18:49) [15]


> Vovan#1   (15.09.06 18:43) [14]

Хм, хотел сделать доброе дело, но корявые веб-дизайнеры всё обломили :-(



Страницы: 1 вся ветка

Текущий архив: 2006.10.08;
Скачать: CL | DM;

Наверх




Память: 0.51 MB
Время: 0.086 c
15-1158417747
*Ламер*
2006-09-16 18:42
2006.10.08
Глянте что откапал.


15-1158072079
zdm
2006-09-12 18:41
2006.10.08
Borland Developer Studio 2006


15-1158325438
AntiUser
2006-09-15 17:03
2006.10.08
Интересные вопросы.


2-1158470909
Fan
2006-09-17 09:28
2006.10.08
Нужна помощь


2-1158770717
1519
2006-09-20 20:45
2006.10.08
Телефон