Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];

Вниз

Интересно работает оптимизатор...   Найти похожие ветки 

 
Delirium   (2003-10-30 11:07) [0]

{$O-} или {$O+}
procedure TForm1.Button1Click(Sender: TObject);
var
i:Integer;
arr:Array[1..3] of Real;
s:Real;
begin
s:=10;
i:=4;
arr[i]:=50;
ShowMessage(FloatToStr(s));
end;

Как показал эксперимент s=10 при {$O-} и s=50 при {$O+}, но!,
ошибка "out of bounds" не появляется ни в одном случае, как сие оценить?


 
Skier   (2003-10-30 11:09) [1]

{$R+} ?


 
Delirium   (2003-10-30 11:13) [2]

Опа, а про то, что {$R} по умолчанию "-", я и не подумал...
Ну ладно, а как быть с оптимизатором, откуда разные значения?


 
Skier   (2003-10-30 11:17) [3]


> Ну ладно, а как быть с оптимизатором, откуда разные значения?

Х.З. :)


 
cyborg   (2003-10-30 12:57) [4]

Выравнивание видимо, либо переменные в регистрах, старая в регистре, а присваиваешь в память.


 
Anatoly Podgoretsky   (2003-10-30 13:01) [5]

Delirium © (30.10.03 11:13) [2]
Одну операцию он выпольнил в регистрах и не испортил памяти, а другую наоборот.
Говорить о каких то рузульратах при неправильной программе грешно. Если отключена авторопверка диаапазовнов, то ее надо проводить вручную. А различие именно в регистровых операциях.


 
icWasya   (2003-10-30 14:19) [6]

короче, у меня получилось, что
при {$O+}
адреса переменных выглядят так
arr[1] [ebp-$2c]
arr[2] [ebp-$24]
arr[3] [ebp-$1c]
несуществующий arr[4] [ebp-$14]
s [ebp-$04]

то есть массив занимает не 24, а 32 байта; s и arr[4] занимают разные ячейки памяти , и соответственно в конце S =10

при {$O-}
адреса переменных выглядят так
arr[1] [ebp-$2c]
arr[2] [ebp-$24]
arr[3] [ebp-$1c]
несуществующий arr[4] [ebp-$14]
s [ebp-$14]

то есть массив занимает 24 байта; s и arr[4] занимают одну и ту же ячейку памяти , и соответственно в конце S =50


 
Ketmar   (2003-10-30 15:47) [7]

ну дык оптимизатор -- он на то и оптимизатор. наивно ожидать соответствие "один к одному" в оптимизированной программе.
а, кстати, статическую проверку диапазонов могли бы делать всегда. ведь несложно, а приятно. а то ведь $R, гад, он ещё и на присвоения влияет. типа:
var
a: SmallInt;
b: Integer;

b := -123456789;
a := b;

при R+ радостно грохнется. не уверен, что это логичное поведение. имхо, было бы удобней считать это переполнением, а не нарушением диапазона.


 
Anatoly Podgoretsky   (2003-10-30 16:13) [8]

Ketmar © (30.10.03 15:47) [7]
Это логичное поведение или ты берешь правильность на себя или ты позволяешь это сделать компилятору, ну это разница логически-филосовская, но это больше нарушения диапазона, b в a не помещается, а вот такая операция a:=a+1 вот здесь уже переполнение.


 
Ketmar   (2003-10-30 16:31) [9]

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


 
Anatoly Podgoretsky   (2003-10-30 16:32) [10]

Ну он исправится


 
han_malign   (2003-10-30 16:41) [11]

А вам не кажется, что, уважающий себя, оптимизатор выкинет строчку arr[i]:=50;(да и arr:Array[1..3] of Real; - туда же), т.к. это значение нигде не используется(уж Hint-ы выдаст точно).

> не 24, а 32 байта
- помоему - бред, даже в VC, максимальное выравнивание данных - на границу 8 байт, на параграф только код равняется. Разве, что для гипотетического использования MMX, который в Delphi не поддерживается, и к тому же целочисленный... Не знаю, может в FPU есть команда со счетверенным 256-битным операндом...


 
Ketmar   (2003-10-30 16:59) [12]

ну да, кстати. по идее весь код до ShowMeswsage (вместе с переменными) должен быть выкинут, а FloatToStr преобразован в вызов функции с параметром-константой. как поведёт себя дельфи, мне проверять лень %-)
и вообще, мы тут про $R+ говорим, при чём тут какие-то оптимизаторы?! %-)


 
Delirium   (2003-10-30 17:49) [13]

> "по идее весь код до ShowMeswsage (вместе с переменными) должен быть выкинут"

Это с чего?

begin
s:=10; // s используется в FloatToStr
i:=4; // i исползуется в arr[i]
arr[i]:=50; // собственно arr[i] нигде не используется,
// но такие операции вообще не выбрасываются компилятором,
// даже если было бы напиано arr[1]:=50; - мало-ли что
// я модифицирую через этот массив?
ShowMessage(FloatToStr(s));
end;


 
han_malign   (2003-10-30 17:59) [14]

Ничего он не выкидывает:
{$O+}
add esp,-$20
s:=10;
xor eax,eax
mov [esp],eax
mov [esp+$04],$40240000
i:=4;
mov eax,4
arr[i]:=50;
xor edx,edx
mov [esp+eax*8],edx //esp+$20
mov [esp+eax*8+$04],$40490000 //esp+$24

{$O-}
push ebp
mov ebp,esp
add esp,-$30 //esp
mov [ebp-$14],edx //esp+$1c
mov [ebp-$04],eax //esp+$2c
s:=10;
xor eax,eax
mov [ebp-$10],eax //esp+$20
mov [ebp-$0c],$40240000 //esp+$24
i:=4;
mov [ebp-$08],4 //esp+$28
arr[i]:=50;
mov eax,[ebp-$08]
xor edx,edx
mov [ebp+eax*8-$38],edx //ebp-$18 //esp+$18
mov [ebp+eax*8-$34],$40490000 //ebp-$14 //esp+$1c

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

В первом случае, явно адрес возврата обнуляется, и все это падает...

Тестовая програмка: program opt;
{$APPTYPE CONSOLE}
uses Windows;
{$O+}
var a: extended;
type tt=class
public
procedure Test(Sender: pointer);
end;
procedure tt.Test(Sender: pointer);
var
i:Integer;
arr:Array[1..3] of Real;
s:Real;
begin
s:=10;
i:=4;
arr[i]:=50;
Writeln(s);
end;
var t: tt;
begin
t:=tt.Create;
t.Test(nil);
t.Free;
end.


 
Ketmar   (2003-10-30 18:25) [15]

>Delirium
а это из Data Flow Analysis следует. по исходнику ЯСНО, что: arr -- локальна, и ни разу нигде не используется. следовательно, i -- тоже не используется (потому что arr уже выкинули на предыдущем шаге). значение a известно на стадии компиляции, и потому смело может быть заменено на константу (не забываем, все переменные -- локальные, модификаторы absolute отсутствуют). предлагаю по этому поводу почитать "дракона" %-)
а то, что оптимизатор в дельфи далеко не лучший, это, кажется, общеизвестный факт. зато быстрый. это тоже факт.



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

Форум: "Потрепаться";
Текущий архив: 2003.11.24;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.48 MB
Время: 0.011 c
14-79129
MPS
2003-11-01 15:07
2003.11.24
Группы новостей


1-78996
Silver_
2003-11-10 16:45
2003.11.24
как правельно обратится к обьекту ТАКИМ образом.


1-78900
_jek
2003-11-14 18:58
2003.11.24
Текстовые файлы и ADO


3-78810
чайник
2003-11-05 08:39
2003.11.24
Обход системной ошибки


6-79074
oduvan
2003-09-26 17:02
2003.11.24
Помогите с UDP (indy)





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский