Форум: "Основная";
Текущий архив: 2003.01.30;
Скачать: [xml.tar.bz2];
ВнизБаг в компиляторе? неверное присвоение локалькой переменной Найти похожие ветки
← →
zavisalych (2003-01-22 10:26) [0]вот, наткнулся на замечательные грабли:
type TMyObject1 = class(TObject)
...
end;
TMyObject2 = class(TObject)
...
AnObject1: TMyObject1;
end;
procedure Proc1(AnObject2: TMyObject2);
var LocalObject: TMyObject1;
begin
// здесь через Watches явно вижу, что AnObject2 <> nil
// а также AnObject2.AnObject1 <> nil
// LocalObject - ессно, variable not accesible due ...
// делаем присвоение:
LocalObject := AnObject2.AnObject1;
// и видим просто класс: LocalObject: nil !!!
...
end;
если же перед присвоением явно указать, что LocalObject := nil (и что-нибудь с ним сделать, чтобы компилятор не соптимизировал этот код, например, "if LocalObject = nil then ;")
то все нормально - присвоение проходит на ура!
Что это? баг компилятора или что?
← →
Calm (2003-01-22 10:35) [1]Если LocalObject в процедуре нигде не используется, то опраторы, присваивающие ему значения могут быть пропущены линковщиком
← →
Digitman (2003-01-22 10:35) [2]Покажи код инициализации переменной AnObject2 и поля AnObject1 ПЕРЕД тем, как ты их на nil "щупаешь" в отладчике
← →
zavisalych (2003-01-22 10:36) [3]используются, и, естественно, выдают AccessViolation :(
← →
zavisalych (2003-01-22 10:49) [4]коды инициализации _очень_ далеко, но если от них что-то зависит - то вот они.
AnObject2 := TMyObject2.CreateMyObject(self,TheObject1);
//Вот сам конструктор где присваивается AnObject1
constructor TMyObject2.CreateMyObject(
AOwner: TComponent; MyObject1: TMyObject1);
begin
AnObject1 := MyObject1;
...
end;
а еще глубже - это создание TheObject1 (по правде говоря, это - потомок TCollectionItem, создается с помощью Add), в общем - все запущено
← →
Игорь Шевченко (2003-01-22 10:58) [5]Сдается мне, что баг не в компиляторе.... :-)
← →
Digitman (2003-01-22 11:00) [6]да никаких багов нет) ... просто - особенности работы оптимизатора
если же тебя в 1-ю очередь таки волнует именно причина AV, то сделай так :
if Assigned(AnObject2) then
try
LocalObject := AnObject2.AnObject1;
except
on e:EAccessViolation do ...
// объект, ссылка на который лежит в AnObject2, не существует !
// либо в AnObject2 - "мусор"
end;
if Assigned(LocalObject) then
try
LocalObject.SomeMethod;
except
on e:EAccessViolation do ...
// объект, ссылка на который лежит в LocalObject, не существует !
// либо в поле AnObject1 - "мусор"
end;
← →
zavisalych (2003-01-22 11:58) [7]Нет, Digitman, ты не понимаешь. К сожалению, мне пришлось вырвать все из контекста. Все перечисленные объекты _существуют_ и заебато работают и до и после приведенного кода, что собственно доказывается тем фактом, что после _второго_ присваивания все работает на ура! И если уж на то пошло, это не фича, а бага работы оптимизатора!
← →
Digitman (2003-01-22 12:07) [8]раз все "з$$$$то работает", чего ты тогда уперся и полез выяснять, что тебе там на самом деле дебагер показывает ?
чтобы дебагер не "мудрил", контролируемые ц/ч величины д.б. в памяти, а не в РОН.
оптимизатор же не разместит в памяти ссылку на объект до тех пор, пока ты не будешь явно обращаться к св-вам/методам этого объекта
вот и думай после этого, почему ты выдернул это из контекста)
как раз предыдущий и последующий код очень важен для понимания сути !
← →
han_malign (2003-01-22 12:21) [9]А в CPU View, не судьба посмотреть, где жуки завелись - в оптимизаторе или в голове???
К тому-же глюк оптимизатора всегда можно проверить, сделав {$O-}...
З.Ы. Я пока-что видел только единственный глюк оптимизации - со значением счетчика цикла For...
З.З.Ы. И надо быть "гением", чтобы отлаживаться с включеной оптимизацией...
← →
McSimm (2003-01-22 12:53) [10]
> Я пока-что видел только единственный глюк оптимизации -
> со значением счетчика цикла For...
Только это никакой не глюк.
← →
NailS (2003-01-22 12:56) [11]
> McSimm © (22.01.03 12:53)
Тогда что?
← →
McSimm (2003-01-22 13:04) [12]Да ничего.
Нормальная работа оптимизатора.
В циклах, в которых важно только количество исполнений, а не значение счетчика оптимизатор формирует немного более эффективный код, не изменяющий сути.
← →
NailS (2003-01-22 13:44) [13]Во-во.
Давно было (года 2 назад D5), могу описать ситуацию не точно.
Простой цикл
что то типа этого
for i := 0 ..... do if ...[i] then ...
падал на оптимизированом коде.
Поиски причины привели к тому, что оптимизатор сначала пытался выполнить if и подсовывал туда переменную i, которая была еще с мусором.
В других похожих циклах ситуация не воспроизводилась.
← →
McSimm (2003-01-22 14:49) [14]Позволю себе выразить сомнение по этому поводу.
Другими словами - не поверю в то, что работа оптимизатора приводит к неверной работе программы, пока не воспроизведу такой код у себя.
← →
Digitman (2003-01-22 15:40) [15]
> подсовывал туда переменную i, которая была еще с мусором
Полная ерунда !
← →
NailS (2003-01-22 16:57) [16]
> Полная ерунда !
А я о чем?
> Другими словами - не поверю в то, что работа оптимизатора
> приводит к неверной работе программы, пока не воспроизведу
> такой код у себя.
Сам бы не поверил, если бы не натолкнулся.
Но отключение оптимизации помогло.
← →
Anatoly Podgoretsky (2003-01-22 17:03) [17]Полная ерунда !
← →
Palladin (2003-01-22 17:05) [18]
> подсовывал туда переменную i, которая была еще с мусором
"ну вы блин даете"
← →
Palladin (2003-01-22 17:10) [19]а как было определено что она (i) еще с мусором?
← →
NailS (2003-01-22 17:13) [20].
> а как было определено что она (i) еще с мусором
ListIndexOutOfBounds(8-значное число)
Кода нет, было давно, доказать что либо невозможно.
На этом можно и закончить
Страницы: 1 вся ветка
Форум: "Основная";
Текущий архив: 2003.01.30;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.008 c