Сейчас в ящик упало письмо, с просьбой помочь исправить косяк с выводом в 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.
Понравилось? Кликни Лайк, чтобы я знал, какой контент более интересен читателям. Заметку пока еще никто не лайкал и ты можешь быть первым
Забавно!!!
P.S. Сейчас так не учат (по крайней мере, в книжках так не пишут)...
"Всегда инициализируйте внутренние переменные!" - гласит одно из великих правил.
Да, реально повезло))).
Я всегда инициализирую, поэтому даже не знал о таком приколе оптимизатора. Но благодаря этому студенту, которому реально повезло, что объявленная переменная оказалась равна aCol только потому, что aCol не используется, буду знать. Буду ли я использовать этот трюк?
Конечно же нет. Никогда в жизни, потому что компилятор может изменится, а потом фиг вспомнишь, почему код перестал работать.
Учат... не учат... У меня в универе вроде бы нормально учат код писать, но бывает такого насмотришься у одногруппников)))
Все равно забавно. Главное что до истины докопались. Иногда начинающие люди прошибают лбом и не такие стены. :)
Да...
Бывает, от усталости, проморгаешь явную ахинею, а потом ЭТО откампилишь...
А потом, проспавшись :), улучШИШь :) и всё,
код перестал работать. Начинается отладка и
удивляешся, как такое бывает.
Косяк сплошной, а не оптимизатор
Хотите найти еще что-то интересное почитать? Можно попробовать отфильтровать заметки на блоге по категориям.