Случайное везение из-за оптимизатора Delphi


9 0

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

Первое, что меня поразило - это код. В нем использовались метки Label и оформление было ужасно. Если так сейчас учат, то мне жаль парня, потому что его на работу не возьмут после такой учебы. Но еще больше, меня поразил следующий код:

procedure TForm1.Tabl1SelectCell(Sender: TObject; ACol, ARow: Integer;
  var CanSelect: Boolean);
var
  e:integer;
begin
  case e of
   1: Код
   2: Код  
  end
end;

Я бы никогда не догадался, что переменная e всегда будет равна значению текущей колонки. Я не знаю, это специально так написано, или случайность, но просто гениально. Дело в том, что переменная ACol, которая передается в метод - не используется. При включенной оптимизации компилятор почему-то начал использовать память переменной ACol именно для хранения e. Я не мог сообразить, как это происходит и позвал начальника, чтобы он взглянул своим взглядом. Он предложил добавить переменные вокруг e:

var
  index:Integer;
  e:integer;
  index1:Integer;

Не помогло, и я сразу не понял почему, но теперь уже все ясно - оптимизация компилятора не использовала перемнные и не выделяла память, потому что в коде небыло обращения к index. Когда поступило предложение отключить оптимизацию, e всегда стала равной нулю.

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


Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым


Комментарии

CLS

11 Декабря 2008

Забавно!!!
P.S. Сейчас так не учат (по крайней мере, в книжках так не пишут)...


Следящий

11 Декабря 2008

"Всегда инициализируйте внутренние переменные!" - гласит одно из великих правил.


plaha

11 Декабря 2008

Да, реально повезло))).


Михаил Фленов

11 Декабря 2008

Я всегда инициализирую, поэтому даже не знал о таком приколе оптимизатора. Но благодаря этому студенту, которому реально повезло, что объявленная переменная оказалась равна aCol только потому, что aCol не используется, буду знать. Буду ли я использовать этот трюк?

Конечно же нет. Никогда в жизни, потому что компилятор может изменится, а потом фиг вспомнишь, почему код перестал работать.


Infinity

11 Декабря 2008

Учат... не учат... У меня в универе вроде бы нормально учат код писать, но бывает такого насмотришься у одногруппников)))


Johnny_Viper

11 Декабря 2008

Все равно забавно. Главное что до истины докопались. Иногда начинающие люди прошибают лбом и не такие стены. :)


Константин

06 Января 2009

Да...
Бывает, от усталости, проморгаешь явную ахинею, а потом ЭТО откампилишь...
А потом, проспавшись :), улучШИШь :) и всё,
код перестал работать. Начинается отладка и
удивляешся, как такое бывает.


Pola

08 Мая 2009

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

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

[code]program Project1;

{$APPTYPE CONSOLE}

function fun: byte;
var i: byte;
begin
  fun:=i;
end;

function pro(i, n:byte): integer;
begin
  if i+1=n then writeln(fun)
  else pro(n-1,n);
end;

var n:byte;

begin
  randomize;
  n:= random(100)+2;
  writeln('n=',n);
  write('fun=');
  pro(1,n);
  readln
end.
[/code]результат вызова fun - это n :)
а вовсе не случайное значение-мусор


CodeM@ster

25 Декабря 2009

Косяк сплошной, а не оптимизатор


Добавить Комментарий

Еще что-нибудь

Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.

О блоге

Программист, автор нескольких книг серии глазами хакера и просто блогер. Интересуюсь безопасностью, хотя хакером себя не считаю

Обратная связь

Без проблем вступаю в неразборчивые разговоры по e-mail. Стараюсь отвечать на письма всех читателей вне зависимости от страны проживания, вероисповедания, на русском или английском языке.

Пишите мне