Текущий архив: 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
> Это как это? Мне надо получить адрес объекта. Какая копия?
- ты этот адрес не только получаешь, но и передаешьOUTPUT:
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;
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). Да и видно, где прямая адресация,
> а где косвенная.
- разница появляется ВНУТРИ функции, при передаче параметра КОПИРОВАНИЯ НЕ ПРИСХОДИТ, адресация в данном случае - всегда прямая. Строка копируется ТОЛЬКО при изменении, или действиях которые МОГУТ привести к изменению.OUTPUT:
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;
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