Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Баг в компиляторе? неверное ;присвоение локалькой переменной [D6, WinXP]


zavisalych ©   (2003-01-22 10:26:00) 

вот, наткнулся на замечательные грабли:

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 ;")
то все нормально - присвоение проходит на ура!

Что это? баг компилятора или что?


NailS   (2003-01-22 17:13:00) [1]

.
> а как было определено что она (i) еще с мусором

ListIndexOutOfBounds(8-значное число)

Кода нет, было давно, доказать что либо невозможно.
На этом можно и закончить


Palladin   (2003-01-22 17:10:00) [2]

а как было определено что она (i) еще с мусором?


Palladin   (2003-01-22 17:05:00) [3]


> подсовывал туда переменную i, которая была еще с мусором

"ну вы блин даете"


Anatoly Podgoretsky   (2003-01-22 17:03:00) [4]

Полная ерунда !


NailS   (2003-01-22 16:57:00) [5]


> Полная ерунда !

А я о чем?


> Другими словами - не поверю в то, что работа оптимизатора
> приводит к неверной работе программы, пока не воспроизведу
> такой код у себя.

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


Digitman   (2003-01-22 15:40:00) [6]


> подсовывал туда переменную i, которая была еще с мусором


Полная ерунда !


McSimm   (2003-01-22 14:49:00) [7]

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


NailS   (2003-01-22 13:44:00) [8]

Во-во.
Давно было (года 2 назад D5), могу описать ситуацию не точно.
Простой цикл
что то типа этого
for i := 0 ..... do if ...[i] then ...
падал на оптимизированом коде.
Поиски причины привели к тому, что оптимизатор сначала пытался выполнить if и подсовывал туда переменную i, которая была еще с мусором.
В других похожих циклах ситуация не воспроизводилась.


McSimm   (2003-01-22 13:04:00) [9]

Да ничего.
Нормальная работа оптимизатора.

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


NailS   (2003-01-22 12:56:00) [10]


> McSimm © (22.01.03 12:53)

Тогда что?


McSimm   (2003-01-22 12:53:00) [11]


> Я пока-что видел только единственный глюк оптимизации -
> со значением счетчика цикла For...

Только это никакой не глюк.


han_malign   (2003-01-22 12:21:00) [12]

А в CPU View, не судьба посмотреть, где жуки завелись - в оптимизаторе или в голове???
К тому-же глюк оптимизатора всегда можно проверить, сделав {$O-}...
З.Ы. Я пока-что видел только единственный глюк оптимизации - со значением счетчика цикла For...
З.З.Ы. И надо быть "гением", чтобы отлаживаться с включеной оптимизацией...


Digitman   (2003-01-22 12:07:00) [13]

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

чтобы дебагер не "мудрил", контролируемые ц/ч величины д.б. в памяти, а не в РОН.
оптимизатор же не разместит в памяти ссылку на объект до тех пор, пока ты не будешь явно обращаться к св-вам/методам этого объекта

вот и думай после этого, почему ты выдернул это из контекста)
как раз предыдущий и последующий код очень важен для понимания сути !


zavisalych   (2003-01-22 11:58:00) [14]

Нет, Digitman, ты не понимаешь. К сожалению, мне пришлось вырвать все из контекста. Все перечисленные объекты _существуют_ и заебато работают и до и после приведенного кода, что собственно доказывается тем фактом, что после _второго_ присваивания все работает на ура! И если уж на то пошло, это не фича, а бага работы оптимизатора!


Digitman   (2003-01-22 11:00:00) [15]

да никаких багов нет) ... просто - особенности работы оптимизатора

если же тебя в 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;


Игорь Шевченко   (2003-01-22 10:58:00) [16]

Сдается мне, что баг не в компиляторе.... :-)


zavisalych   (2003-01-22 10:49:00) [17]

коды инициализации _очень_ далеко, но если от них что-то зависит - то вот они.

AnObject2 := TMyObject2.CreateMyObject(self,TheObject1);

//Вот сам конструктор где присваивается AnObject1
constructor TMyObject2.CreateMyObject(
AOwner: TComponent; MyObject1: TMyObject1);
begin
AnObject1 := MyObject1;
...
end;

а еще глубже - это создание TheObject1 (по правде говоря, это - потомок TCollectionItem, создается с помощью Add), в общем - все запущено


zavisalych   (2003-01-22 10:36:00) [18]

используются, и, естественно, выдают AccessViolation :(


Calm   (2003-01-22 10:35:00) [19]

Если LocalObject в процедуре нигде не используется, то опраторы, присваивающие ему значения могут быть пропущены линковщиком


Digitman   (2003-01-22 10:35:00) [20]

Покажи код инициализации переменной AnObject2 и поля AnObject1 ПЕРЕД тем, как ты их на nil "щупаешь" в отладчике


Наверх

Титульная страница Поиск, карта сайта Написать письмо