Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Основная";
Текущий архив: 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.009 c
1-96776
Mikle
2003-01-22 20:43
2003.01.30
Параметрический запуск приложения


1-96802
REA
2003-01-17 16:08
2003.01.30
Печать картинки


14-97017
ЖаннаН
2003-01-13 20:44
2003.01.30
HEELP Me


14-96954
MystiX
2003-01-12 19:35
2003.01.30
Httpdl


6-96910
Nord-Ost
2002-12-04 15:32
2003.01.30
А куда девался TClientSocket?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский