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

Вниз

Сенсация! Код initialization может не выполнятся!   Найти похожие ветки 

 
Игорь Шевченко ©   (2006-07-13 11:10) [80]

MikProg ©   (13.07.06 11:07) [79]

Я еще раз обращаю твое внимание на то, что проблема у тебя, а не у отвечающих. И решать ее надо тебе, а не им :)


 
isasa ©   (2006-07-13 11:16) [81]

Немного изуродовал, для детализации. Разница, все таки, есть. А то я начал волноваться. :)

procedure TForm1.FormCreate(Sender: TObject);
begin
FStr := "Bill Gates";
end;

procedure WithoutVarAndConst(S: string);
begin
//  S := S + ";";
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure WithVar(var S: string);
begin
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure WithConst(const S: string);
begin
  Form1.memo1.Lines.Add(Format("@FStr: %p, @S: %p, @FStr[1]: %p, @S[1]: %p, FStr: %s, S: %s",
  [@Form1.FStr, @S, @Form1.FStr[1], @S[1], Form1.FStr, S]));
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
WithoutVarAndConst(FStr)
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
WithVar(FStr)
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
WithConst(FStr)
end;

Результат

@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F4200, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 008F1D40, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates


 
MikProg ©   (2006-07-13 11:24) [82]


> То что код секции иниц-ии не отметил себя в файле протокола,
>  еще не говорит о невызове секции.

"код секции иниц-ии не отметил себя в файле протокола" и не произшло возникновение исключительной ситуации.

А теперь говорит?


 
MikProg ©   (2006-07-13 11:30) [83]


> И решать ее надо тебе, а не им :)

Ну и...? Че дальше то? Вы не читали хохму про "реалтайм" удаление аппендицита отоларингологом по советам в чате. Здесь все идет по тому сценарию. Пока не хватает только одного персонажа - того который все опошлит. :)


 
Сергей М. ©   (2006-07-13 11:39) [84]


> MikProg ©   (13.07.06 11:24) [82]


Цитата из справки:

..in Delphi, the application first executes the initialization section of all the units used by the application

Борланд, по-твоему, врет ?


 
Игорь Шевченко ©   (2006-07-13 11:52) [85]

MikProg ©   (13.07.06 11:30) [83]


> Ну и...? Че дальше то?


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


 
GrayFace ©   (2006-07-13 12:00) [86]

isasa ©   (12.07.06 14:08) [39]
Так это, я тут напрягся и вспомнил, что передача параметра по значению еще со времен Турбо-Паскаля - только то, что меньше или равно длине регистра. :)
Остальное, все равно, по ссылке.

Насколько я знаю, ShortString, массивы конечной длины и record"ы передается по значению. Впрочем, сам тестов не гонял.

MikProg ©   (12.07.06 14:52) [55]
function LogFileName: string;

Про ChangeFileExt не забывай.


 
han_malign ©   (2006-07-13 12:10) [87]

OFFTOP

> Разница, все таки, есть. А то я начал волноваться.

- разницы нет, просто ты совершаешь действие которое может потенциально привести к изменению строки(передача в функцию @s[1]), поэтому делается UniqueString(уже внутри функции)... Так что волнуйся дальше.
А неявный try finaly - действительно имеет место...


 
isasa ©   (2006-07-13 12:36) [88]

han_malign ©   (13.07.06 12:10) [87]
- разницы нет, просто ты совершаешь действие которое может потенциально привести к изменению строки(передача в функцию @s[1]), поэтому делается UniqueString(уже внутри функции)...


Это как это? Мне надо получить адрес объекта. Какая копия?
@s[1] == addr(s[1]) - использую для передачи адреса буфера, что не так.


 
han_malign ©   (2006-07-13 12:50) [89]

OFFTOP

> Это как это? Мне надо получить адрес объекта. Какая копия?

- ты этот адрес не только получаешь, но и передаешь
  procedure StrInfo(aCmnt: string; str: Pointer);
  type
    PStrRec = ^StrRec;
    StrRec = packed record
      refCnt: Longint;
      length: Longint;
    end;
  var _p: PStrRec;
  begin
     _p:= PStrRec(str);
     if(_p = nil)then Writeln(aCmnt, ": nil")
     else begin
        dec(_p);
        Writeln(aCmnt, ": [",HexDWORD(DWORD(str)),"] Ref: ", _p.refCnt)
     end;
  end;
var _s: string;
  procedure ByVal(s: string);
  begin
     StrInfo("ByValO   ", Pointer(_s));
     StrInfo("ByValP   ", Pointer(s));
     Writeln(HexDWORD(DWORD(@s[1])));
     StrInfo("ByValO~  ", Pointer(_s));
     StrInfo("ByValP~  ", Pointer(s));
  end;
OUTPUT:
ByValO   : [0083000C] Ref: 2
ByValP   : [0083000C] Ref: 2
0083001C
ByValO~  : [0083000C] Ref: 1
ByValP~  : [0083001C] Ref: 1


 
evvcom ©   (2006-07-13 12:51) [90]

> [77] isasa ©   (13.07.06 10:40)

Это частный случай шаманства оптимизатора.


 
MikProg ©   (2006-07-13 12:59) [91]


> или предоставляй всю информацию для воспроизведения своей
> проблемы,

Включите здравый смысл:
Если бы я знал в чем заключается вся информация, я бы ее уже дал.
Если добровольные помощники знали в чем заключается вся информация, то они бы ее уже запросили.
А пока имеем ... то что имеем :)
"Дохтор, у меня это!"  ©


 
MikProg ©   (2006-07-13 13:02) [92]


> Про ChangeFileExt не забывай.
>

Это глюк такой - я прекрасно знаю о ее существовании, но за последние сто лет ни разу не использовал.
"Вы хотите поговорить об этом?" ©


 
isasa ©   (2006-07-13 13:03) [93]

Ладно, утомили. :)
Не будем лезть в детали(счетчик ссылок, длина). Разница более чем в 16 байт (2 x long). Да и видно, где прямая адресация, а где косвенная.
Результат

@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F4200, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 008F1D40, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates
@FStr: 008F1D40, @S: 0012F624, @FStr[1]: 008F2004, @S[1]: 008F2004, FStr: Bill Gates, S: Bill Gates


 
Игорь Шевченко ©   (2006-07-13 13:05) [94]

MikProg ©   (13.07.06 12:59) [91]


> Включите здравый смысл:
> Если бы я знал в чем заключается вся информация, я бы ее
> уже дал.


Включил. Поясняю: Если проблема воспроизводится у тебя, значит, у тебя есть вся информация по ней, которую ты вполне можешь дать. Если проблема не воспроизводится, значит, проблемы нет. Если проблема не воспроизводится у тебя, но воспроизводится в ближайшем окружении, ты можешь найти 10 отличий своего окружения от того, где воспроизводится проблема, устранить их, воспроизвести проблему, и если после этого она не решится, дать всю информацию более опытным товарищам.


 
Плохиш ©   (2006-07-13 13:38) [95]


> Игорь Шевченко ©   (13.07.06 13:05) [94]

Тааак долго :-( Можно всех на "слабо" развести ;-)


 
han_malign ©   (2006-07-13 14:03) [96]

OFFTOP

> Это частный случай шаманства оптимизатора.

- нет, это общий случай передачи по значению "smart pointer" динамических объектов. Оптимизатор здесь вообще не причем.

> Не будем лезть в детали(счетчик ссылок, длина). Разница
> более чем в 16 байт (2 x long). Да и видно, где прямая адресация,
>  а где косвенная.

- разница появляется ВНУТРИ функции, при передаче параметра КОПИРОВАНИЯ НЕ ПРИСХОДИТ, адресация в данном случае - всегда прямая. Строка копируется ТОЛЬКО при изменении, или действиях которые МОГУТ привести к изменению.

  procedure ByVal(s: string);
  begin
     StrInfo("ByValO   ", Pointer(_s));
     StrInfo("ByValP   ", Pointer(s));
     if(Pointer(s) <> @s[1])
     then Writeln("Pointer(s) <> @s[1]")
     else Writeln("Pointer(s) = @s[1]");

     Writeln(HexDWORD(DWORD(@s[1])));
     StrInfo("ByValO~  ", Pointer(_s));
     StrInfo("ByValP~  ", Pointer(s));
  end;
OUTPUT:
ByValO   : [0083000C] Ref: 2
ByValP   : [0083000C] Ref: 2
Pointer(s) = @s[1]
0083001C
ByValO~  : [0083000C] Ref: 1
ByValP~  : [0083001C] Ref: 1


 
MikProg ©   (2006-07-13 14:18) [97]


> Если проблема не воспроизводится, значит, проблемы нет.

Именно так я обслуживаю клиентуру за деньги. Вы же не платный саппорт? Если бы вы им были то я и разговаривал с вами по другому. А когда помогаешь по дружбе - совсем другое дело. Другу я честно отвечу "не знаю", а не начну дурить мозги что "это не баг, это фича" ©.

> дать всю информацию более опытным товарищам.

Которые, в абсолютном большинстве случаев, смогут дать ответ только если уже сталкивались с подобной хренью вживую (вы то сами верите, что господа "опытные товарищи" бросятся воспроизводить оперативную обстановку, чтобы помочь мне :) или верите что все проблемы они могут решить слегка наморщив лоб? :)) ).
Собс-но об этом и вопрос: "Кто наступал на такие грабли?" Ответ пока: 1(один) и совсем по другому поводу и его решение совпадает с моим (которое меня не удовлетворяет).


> Можно всех на "слабо" развести ;-)

Так ведь и развел. Только оно в действительности оказалось "слабо". :)


 
MikProg ©   (2006-07-13 14:21) [98]

Удалено модератором
Примечание: Offtopic


 
Игорь Шевченко ©   (2006-07-13 15:10) [99]

MikProg ©   (13.07.06 14:18) [97]


> Именно так я обслуживаю клиентуру за деньги. Вы же не платный
> саппорт?


Дорогой друг, форум точно также не является платным суппортом, ты что-то здорово перепутал. Поэтому отвечать тебе каждый волен, как ему заблагорассудится, в рамках правил этого форума.


> А когда помогаешь по дружбе - совсем другое дело.


А если не затруднит, ты не скажешь, кому ты на данном форуме успел помочь по дружбе ? :)


> Так ведь и развел. Только оно в действительности оказалось
> "слабо".


Нет, просто никому не интересно тебе помогать. Только и всего.


 
MikProg ©   (2006-07-13 16:20) [100]


> Нет, просто никому не интересно тебе помогать. Только и
> всего.
>

Зато как интересно рассказывать как бы вы мне замечательно помогли, если бы я  вел себя "правильно". Вам самому времени не жалко?


 
Игорь Шевченко ©   (2006-07-13 16:40) [101]

MikProg ©   (13.07.06 16:20) [100]


> Вам самому времени не жалко?


Я вот ссылку дал, несколькими постами раньше. Ее бы почитать неплохо, там все написано, и про мое время, в том числе :)


 
evvcom ©   (2006-07-14 09:34) [102]

> [96] han_malign ©   (13.07.06 14:03)

Посмотрел код. Действительно оптимизатор оказался не причем. Разница в вызовах с const и без const и var в вызове функции System._LStrAddRef. Но согласитесь, что string все же особенный тип. Поэтому без шаманства все же тут не обходится. Единственное в чем я ошибся, это в шамане. :) Компилятор тут колдует.
Ну а если взять "простой" тип, то при передаче по значению попросту происходит копирование параметра в стеке:
type TRec = record
 aa: Integer;
 bb: Integer;
end;

function SumWithConst(const rec: TRec): Integer;
begin
 Result := rec.aa + rec.bb;
end;

function SumWithoutVarAndConst(rec: TRec): Integer;
begin
 Result := rec.aa + rec.bb;
end;

В результате (оптимизатор выключен):
SumWithConst:begin
push ebp
mov ebp,esp
add esp,-$08
mov [ebp-$04],eax

SumWithoutVarAndConst:begin
push ebp
mov ebp,esp
add esp,-$0c
push esi
push edi
mov esi,eax
lea edi,[ebp-$08]
movsd
movsd


Вот те и копирование. Хотя никакого присвоения не происходит. Так что все-таки

> [49] sniknik ©   (12.07.06 14:40)
> не знал, что оптимизатор стал таким умным

не настолько уж он умён. Кстати и со стрингами, все же вызывается лишний раз (без const) System._LStrAddRef, хотя в коде не предполагалось никаких изменений стринга. Это адреса стрингов не изменились, но подготовка к возможному изменению все же была проведена.


 
MikProg ©   (2006-07-14 22:44) [103]

Проблема решилась включением LayerBase в проект. Чтобы это значило?


 
Игорь Шевченко ©   (2006-07-14 23:26) [104]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?


Изменился порядок выполнения секций Initialization


 
Суслик ©   (2006-07-15 11:33) [105]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
Суслик ©   (2006-07-15 11:33) [106]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
Суслик ©   (2006-07-15 11:33) [107]


> Проблема решилась включением LayerBase в проект. Чтобы это
> значило?

1. нужно сказать спасибо Диме Тимохову :)
2. нужно запоминить, что с initialization бывают некоторые глюки, но их точно не бывает, если все используемые модуля приведены с проекте или в пакетах (если ты их используешь).

ЗЫ. На самом деле с пакетами там тоже не все просто. Ситуация (я тут о ней спрашивал но ушло в историю).
1. есть приложение А
2. есть пакет Б, который приложение А загружает с использованием loadpackage.
3. есть пакет В, который указан в секции requires пакета Б, но про него не знает ничего приложение А.
4. в пакете В есть два модуля М1 и М2.
5. М1 используется (есть в секции uses) в одном из модулей пакета Б.
6. М2 не используется ниииииигде.
В итоге секция инициализации в М2 выполнена не будет.

ЗЫЫ. Надеюсь в примере не ошибся. :)
В итоге при


 
MikProg ©   (2006-07-15 21:59) [108]


> Изменился порядок выполнения секций Initialization

Что? От порядка зависит кто вообще будет инициализирован, а кто упадет в игнор?

>  нужно запоминить, что с initialization бывают некоторые
> глюки,

Похоже я перестану их использовать. Невозможно тестировать весь код!


 
Игорь Шевченко ©   (2006-07-15 22:07) [109]

MikProg ©   (15.07.06 21:59) [108]


> Что? От порядка зависит кто вообще будет инициализирован,
>  а кто упадет в игнор?


Ты переоцениваешь мои телепатические способности - я не знаю твоего кода.


>  Невозможно тестировать весь код!


Возможно.


 
MikProg ©   (2006-07-15 23:47) [110]

Удалено модератором
Примечание: Offtopic


 
Суслик ©   (2006-07-16 00:30) [111]

Удалено модератором
Примечание: Offtopic


 
MikProg ©   (2006-07-16 09:13) [112]

Удалено модератором
Примечание: Offtopic



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

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

Наверх




Память: 0.7 MB
Время: 0.049 c
6-1144449490
vagra
2006-04-08 02:38
2006.08.27
Узнать IP по имени домена


1-1152522186
97
2006-07-10 13:03
2006.08.27
JvSearchFiles из Jedi


2-1153945535
serko
2006-07-27 00:25
2006.08.27
Передача файла!


2-1154762326
12
2006-08-05 11:18
2006.08.27
Можно ли вытащить код из exe


4-1146820955
Dimich1978
2006-05-05 13:22
2006.08.27
получить handle окна по неполному имени