powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Наполняемость переменной при декларации
34 сообщений из 34, показаны все 2 страниц
Наполняемость переменной при декларации
    #39943654
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго дня господа !

Delphi 10.3.3 (64-ibt)
Заметил такую ИСТИНУ (!!!!????) хотел бы уточнить может оптический обман зрения

В процедуре объявил переменную типа ADOConnection (пока не создал объект Create) и она уже не равна Nil ,

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
var
    adoSave:  TADOConnection;
begin
    ......................................
    ......................................
    if adoSave<>Nil then begin 
      ShowMessage('Not_Nil');
      adoSave.Close;       -- соответственно здесь ошибка
      FreeAndNil(adoSave);
    end;
end


Это новый прикол компилятора ?

Спасибо
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943657
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X,

Это старый прикол.

Локальные unmanaged переменные компилятор не инициализирует.

Тебе на строке " if adoSave<>Nil then begin " компилятор должен предупреждение выдавать что переменная не инициализирована.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943659
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
HOME_X,

Это старый прикол.

Локальные unmanaged переменные компилятор не инициализирует.

Тебе на строке " if adoSave<>Nil then begin " компилятор должен предупреждение выдавать что переменная не инициализирована.



Таки "мозг почистил" - ошибка таже
Код: pascal
1.
2.
3.
4.
5.
procedure TForm1.Button4Click(Sender: TObject);
var s: TADOConnection;
begin
  if(S=Nil)then ShowMessage('Nil') else ShowMessage('Not Nil')
end;



Старый ?
В 32-bit 7-ке такого не было...
Это теперь надо отслеживать ВСЕ !!! объекты ?

Локальные unmanaged переменные компилятор не инициализирует.
Если это поле объекта компилятор дейcтвует аналогично ...
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943660
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X,

Это всегда было.
Значения unmanaged переменных инициализируются в созданных классах и глобальных переменных но не в локальных.
Оптимизация! (с)

Значение s в твоем примере может быть каким угодно. В том числе и nil если повезет и в памяти по ее адресу лежат нули.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943661
HOME_X
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Неее - у меня DLL-ка писана под 7-ой (версия не помню точно от какой даты)
Работала с этой "ошибкой" лет 5 и не сваливалась.
Теперь ее переписываю по 64 - bitа

С полями дело обстоит аналогично пример ниже
может необходимо где-то ДОнастроить среду разработки ?


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
type
  TForm1 = class(TForm)
   
    ADOConnection1: TADOConnection;
    procedure Button4Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button4Click(Sender: TObject);
var s: TADOConnection;
begin
  s:=Nil;
  if(ADOConnection1=Nil)then ShowMessage('Nil') else ShowMessage('Not Nil')
end;

end.



Спасибо
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943667
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X
rgreat,

Неее - у меня DLL-ка писана под 7-ой (версия не помню точно от какой даты)
Работала с этой "ошибкой" лет 5 и не сваливалась.


Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
program Project1;

{$APPTYPE CONSOLE}

uses
  SysUtils, classes;

var
  x : TObject;
begin
  Writeln(x=nil);
  readln;
end.


Скомпилировал на Delphi7.

Результат: FALSE.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943671
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
HOME_X
С полями дело обстоит аналогично пример ниже
Не знаю что у тебя там за пример ниже и что в нем не так.

Я вижу что у тебя на форме шлепнут TADOConnection, который естессно не nil изначально, а полноценно инициализированный класс.

Удали с формы ADOConnection1: TADOConnection; и добавь только эту строчку в раздел Public и будет тебе Form1.ADOConnection1=nil.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943675
northener
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
HOME_X
rgreat,
Неее - у меня DLL-ка писана под 7-ой (версия не помню точно от какой даты)
Работала с этой "ошибкой" лет 5 и не сваливалась.

Неповезло. Вот такая это сволочная штука - ошибки работы с памятью.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943699
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Скомпилировал на Delphi7.

Результат: FALSE.

А должно быть TRUE. Глобальные переменные инициализируются всегда, вне зависимости от типа.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943703
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

А в случае основного тела консольного приложения оно локальное или глобальное?

А то я сначала сделал пример где кроме этого было тоже самое но в процедуре, но одинаковый результат меня удивил, а потому я процедуру из примера вырезал.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943706
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Всё что декларируется внутри процедур/функций/методов оно локальное, всё что вне - глобальное.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943708
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Это не ответ.

По крайней мере не совпадающий с объективной реальностью ответ. :)

Вообще я вижу "begin end." в теле проекта как этакий особый случай процедуры.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943709
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Это не ответ

Это почти дословное цитирование бумажной доки от Delphi 5 ;)
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943711
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

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

Взаимоисключающие параграфы.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943712
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Вообще я вижу "begin end." в теле проекта как этакий особый случай процедуры.

Можно проще: лежит на стеке - локальная, лежит в сегменте данных - глобальная.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943714
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Ага, при этом переменные в теле проекта считаются глобальными но при этом не инициализируются.

Я на 10.3 проверил - TRUE.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943716
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

В 10.3.3 - да. В D7 - нет.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943719
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Delphi: МИН НЕТ!

Не знаю, соберётся-ли на Delphi 7, но проверь:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

procedure test2;
var
 i : Integer;
begin
 writeln(Integer(@i));
end;
procedure test;
var
 i : Integer;
begin
 test2;
 writeln(Integer(@i));
end;
var
t : Integer;
begin

 writeln(Integer(@datamark));
 writeln(Integer(@t));
 test;
 readln;

end.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943723
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey,

Только "System." пришлось убить.

Код: plaintext
1.
2.
3.
4231316
4237208
1703760
1703768
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943725
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat
Только "System." пришлось убить.

Логично :)

Результат говорит о том, что переменные декларированные в теле основного модуля являются глобальными. А вот почему семёрка их не обнуляет...
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943726
rgreat
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
rgreat
Только "System." пришлось убить.
А вот почему семёрка их не обнуляет...
20 лет не прошло даром.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943728
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rgreat,

Учитывая это https://stackoverflow.com/a/134191, ситуация выглядит очень странной.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943736
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Попытал я семёрку - глюк оптимизатора. Отключаешь оптимизацию или берёшь адрес от этой переменной и она сразу становится инициализированной :) Порылся в своём старом коде (2003 год):
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
{$OPTIMIZATION OFF}

//
// Оптимизация должна быть выключена, иначе процедура EnumWndProc
// будет работать неправильно. Вероятно, глюк компилятора Delphi 7
//
// P.S.
// Эта ошибка много крови мне попортила...
//
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943749
Все переменные класса должны быть инициализированы в конструкторе. Все глобальные переменные должны быть инициализированы в главном блоке begin или же секции initialization. Так же, переменные имеющие ручную инициализацию динамических данных, должны быть уничтожены в ручную в destructor классе, или же finalization секции.

И не стоит надеяться на удачную случайность мусора в памяти, для значения переменной. Это Кот Шрёдингера .
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943751
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный,

Няшка, тебе череп не жмёт?

ВсеРазумный
Все переменные класса должны быть инициализированы в конструкторе.

1. Переменные класса - это глобальные переменные. Они инициализируются всегда.
2. Но ты то о полях объекта , а они тоже инициализируются всегда.

ВсеРазумный
Все глобальные переменные должны быть инициализированы в главном блоке begin или же секции initialization.

См. выше про глобальные переменные.

ВсеРазумный
переменные имеющие ручную инициализацию динамических данных

Parser error.

У меня фсио
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943754
Kazantsev Alexey

1. Переменные класса - это глобальные переменные. Они инициализируются всегда.
2. Но ты то о полях объекта , а они тоже инициализируются всегда.


Однако объект сам себя не создаст. И объекту не нужно в будущем "adoSave<>Nil" проверять на создание. Так как автор не контролирует - то, что у него в программе. И следовательно лепит костыли.


Kazantsev Alexey

Parser error.


Код: pascal
1.
2.
3.
4.
5.
SetLength(x, n);

...

GetMem(x, N);



Да хоть тот же
Код: pascal
1.
facility := TClass.Create;



Является ручной инициализацией динамических данных, вложенных в класс (Например конструктор) который в будущем следует удалить.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943755
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev Alexey
Delphi: МИН НЕТ!

Не знаю, соберётся-ли на Delphi 7, но проверь:
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils;

procedure test2;
var
 i : Integer;
begin
 writeln(Integer(@i));
end;
procedure test;
var
 i : Integer;
begin
 test2;
 writeln(Integer(@i));
end;
var
t : Integer;
begin

 writeln(Integer(@datamark));
 writeln(Integer(@t));
 test;
 readln;

end.


rgreat
Kazantsev Alexey,

Только "System." пришлось убить.

Код: plaintext
1.
2.
3.
4231316
4237208
1703760
1703768


Kazantsev Alexey
rgreat
Только "System." пришлось убить.

Логично :)

Результат говорит о том, что переменные декларированные в теле основного модуля являются глобальными. А вот почему семёрка их не обнуляет...


во вы парни угораете на карантин
очень интересно зачем вам понадобилось вывести адреса переменных
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943759
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
Однако объект сам себя не создаст.

Однако, речь о дефолтной инициализации переменных.
kealon(Ruslan)
зачем вам понадобилось вывести адреса переменных

Ну дык... Наглядная демонстрация, что стековые переменные находятся далеко от сегмента данных, и интересующая нас переменная лежит именно в сегменте данных.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943771
Kazantsev Alexey
Однако, речь о дефолтной инициализации переменных.


О какой инициализации идёт речь? Это обычный GetMem + FillChar с определённым StorageSize, а в куче процедур у нас стэк обычный.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943773
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
О какой инициализации идёт речь?

О дефолтной. В этом топике. Няшик.
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943774
Kazantsev Alexey,

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

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  c = class
  public
    Test: integer;
    procedure Call1;
    procedure Call2;
    procedure Call3;
  end;

procedure c.Call1;
begin
  writeln(NativeUint(@Test));
end;

procedure c.Call2;
var
  Test5454: integer;
begin
  Test5454 := 45;
  writeln('Call2 ' + NativeUint(@Test5454).ToString + ' : ' + Test5454.ToString);
end;

procedure c.Call3;
var
  Test0: integer;
begin
  writeln('Call3 ' + NativeUint(@Test0).ToString + ' : ' + Test0.ToString);
  writeln(NativeUint(@Test));
end;

var
  t: c;

begin
  try
    t := c.Create;
    t.Call1;
    t.Call2;
    t.Call3;

  except
    on E: Exception do
      writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




38307908
Call2 1703720 : 45
Call3 1703720 : 45
38307908


Задаём в функции Call2 переменную Test5454 со значением 45 и вызываем Call3 и выводим значение переменной Test0

Ну а дальше получаем по губе мусором
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943776
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
По этому я вам сейчас подкину интересную магию

Это не магия, это основы, о которых тут уже писали .
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943777
Kazantsev Alexey,

Усложним пример

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
program Project1;

{$APPTYPE CONSOLE}
{$R *.res}

uses
  System.SysUtils;

type
  c = class
  public
    IsChainTmp: Boolean;
    procedure Call1(IsChain: Boolean = false);
    procedure Call2;
    procedure Call3;
    procedure Test;
  end;

procedure c.Test;
begin

end;

procedure c.Call1;
var
  Test0: integer;
begin
  Randomize;
  Test0 := Random(100) + 1;
  writeln('Test = ' + NativeUint(@IsChainTmp).ToString);
  writeln('Self = ' + NativeUint(@self).ToString);

  IsChainTmp := IsChain;
  if IsChainTmp then
    Call2;

  writeln('Test0(Call1) = ' + NativeUint(@Test0).ToString + ' : ' + Test0.ToString);
end;

procedure c.Call2;
var
  Test1: integer;
begin
  Randomize;
  Test1 := Test1 * Random(50) + 1;
  writeln('Test1(Call2) = ' + NativeUint(@Test1).ToString + ' : ' + Test1.ToString);

  if IsChainTmp then
    Call3;
end;

procedure c.Call3;
var
  Test2: integer;
begin
  writeln('Test2(Call3) = ' + NativeUint(@Test2).ToString + ' : ' + Test2.ToString);
end;

var
  Global: integer;

  t: c;

begin
  try

    writeln('Global ' + NativeUint(@Global).ToString + ' : ' + Global.ToString);

    t := c.Create;
    t.Call1;
    t.Call2;
    t.Call3;

    t.Call1(true);
    t.Call3;

  except
    on E: Exception do
      writeln(E.ClassName, ': ', E.Message);
  end;
  Readln;

end.




Global 4356316 : 0

Test = 37980228
Self = 1703704

Test0(Call1) = 1703696 : 40

Test1(Call2) = 1703700 : 1
Test2(Call3) = 1703700 : 1

Test = 37980228
Self = 1703704

Test1(Call2) = 1703628 : 568830241
Test2(Call3) = 1703584 : 37922016

Test0(Call1) = 1703696 : 48

Test2(Call3) = 1703700 : 16777216
...
Рейтинг: 0 / 0
Наполняемость переменной при декларации
    #39943778
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВсеРазумный
Усложним пример

Могу тебе предыдущую ссылку ещё раз дать. Надо? Адреса стековых переменных меняются? Ну так и вложенность вызовов меняется.
...
Рейтинг: 0 / 0
34 сообщений из 34, показаны все 2 страниц
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Наполняемость переменной при декларации
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]