![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Value assigned to
Gluka © (2002-03-14 02:18:00)Что это за фигня, и как с этим бороться!!!
fenics (2002-03-21 18:42:00) [1]Бедный Gkuka! До чего может ловести беседа десятка програмистов!
Через неделю о его вопросе уже и невспоминали!
fenics (2002-03-21 18:42:00) [2]Бедный Gluka! До чего может ловести беседа десятка програмистов!
Через неделю о его вопросе уже и невспоминали!
Stratos (2002-03-21 14:16:00) [3]К слову о внутренних ошибках:
У меня выдавалась такая после того, как в процедуре написал циклforв немcase ofcbreak. После удаления цикла (break остался) появилась ошибка. По идее, компилятор должен был ругнуться по-хорошему. Может он в больших проектах запутывается.
В общем, едиственное надежное средство отладки - шаманский бубен 8)
Drex (2002-03-21 12:50:00) [4]>>vl_chel
Drex в написанном вами коде переменные CardByte и i не мужны
i:=0; << Смысл?? тут я уже признал свой косяк
CardByte:=0;
Repeat << к чему это относится? Еще внешний цикл, в котором инкремент CardByte"а поэтому CardByte все таки нужен
Byte10:=0;
Bit:=0;
Repeat
i:=CardByte*8+Bit; << CardByte = 0 Смысл??
Case Bit Of {Перевод из двоичного в десятичное}
0:Byte10:=Byte10+Current[i]*128;<<Меняем во всех строчках I на Bit (на CardByte*8+Bit)-так можно ;-)
1:Byte10:=Byte10+Current[i]*64;
2:Byte10:=Byte10+Current[i]*32;
3:Byte10:=Byte10+Current[i]*16;
4:Byte10:=Byte10+Current[i]*8;
5:Byte10:=Byte10+Current[i]*4;
6:Byte10:=Byte10+Current[i]*2;
7:Byte10:=Byte10+Current[i]*1;
End;
Bit:=Bit+1;
i:=i+1;<< зачем увеличивать I (грамотнее inc(I)) Учту, спасибо что без сарказма
Until Bit=8;
Здесь дет инкремент CardByte и Until для внешнего цикла
Rooman (2002-03-20 18:54:00) [5]А алгоритм может быть эффективным. Даже очень. Одно с другим не коррелирует:)
Rooman (2002-03-20 18:39:00) [6]Внук. Наконец мы друг друга поняли. Я не согласен только с тем, что надо говорить на языке высокого уровня. Мне кажется, большинство ошибок программисты допускают как раз по той причине, что они просто не знают того, как это будет в итоге выполняться на самом низком уровне. Я за повышение уровня знаний программистов. Мне кажется, вообще программирование надо изучать не с языков высокого уровня, а как раз с ассемблера, тем более что понять его много проще.
Внук (2002-03-20 14:16:00) [7]>>Rooman
Мне это объяснять не нужно :) Регистровые переменные в C мной использовались, еще когда DOS был нам единственной надеждой и опорой. То, что одна и та же переменная в тексте программы на Паскале может быть по разному представлена на протяжении своего использования в коде на ассемблере, это факт. Но для начинающего (или не очень) программиста, который видит лишь исходный текст своей программы - это одно и тоже. Поэтому я и рассуждаю с точки зрения языка высокого уровня. Судя по репликам (см. самое начало), довольно многие неправильно понимают смысл сообщения, что переменная не используется вообще. Лишь промежуточное значение этой переменной не используется. Теперь мы кажется начали говорить об одном и том же :)
Сейчас моя очередь давать совет вопрошающему: не отключайте оптимизацию и не игнорируйте предупреждения, поскольку они свидетельствуют о том, что Ваш алгоритм настолько неэффективен, что это видно даже компилятору и он берется его грубо править для Вас. Это уже какой-то полуфабрикат получается :)
Rooman (2002-03-20 13:40:00) [8]Общий совет: разделите внутри себя понятия: код на паскале и код на ассемблере. Процессору по барабану, переменную вы задали, или константу, у процессора есть регистры, доступная для него память в данном процессе (вирт.машина) с разными правами доступа (ч/з) и стек. Все регистры и все данные, с которыми оперирует процессор - трех типов: QWORD,DWORD,WORD и BYTE.
Всё! Больше ничего.
Rooman (2002-03-20 13:34:00) [9]Внук: финальный аккорд тебе - то, о чем ты говоришь - это как раз следствие того, о чем говорю я. Потому что наиболее часто встречающаяся ситуация при оптимизации - размещение индукционных переменных в регистрах процессораприводит к тому, что компилятор вынужден выкинуть первую строчку кода:
i:=0;
i:=1;
так как создание индукционной переменной в этой строчке не имеет смысла - она не используется далее.
Обмозгуй это, и ты меня поймешь.
Rooman (2002-03-20 13:26:00) [10]Короче,совет тому, кто задал вопрос - отключи оптимизацию в опциях проекта. Тогда все скомпилируется именно так, как ты написал в своем коде. Но лучше этого не делать и вообще забить (проверить код свой, т.е.):)))
Rooman (2002-03-20 13:16:00) [11]По поводу индукционных переменных:
var i:integer;
procedure doany(var n:integer);stdcall;
i:=1;
doany(i);
i:=2;
doany(i);
i:=3;
doany(i);
Здесь под переменную i однозначно выделяется память.
Так вот, здесь i - для вас это одна переменная, а для компилятора - три разных (смотри дизассемблер):
mov [esp],1 ;первая индукционная переменная (якобы "i")
push esp
call doany
mov [esp],2 ;вторая индукционная переменная (якобы "i")
push esp
call doany
mov [esp],3 ;третья индукционная переменная (якобы "i")
push esp
call doany
Вот это и есть явление индукции переменной.
Данный пример простой - реструктуризации алгоритма при компиляции не происходит, поэтому Warnings не появляется.
А вот в циклах довольно часто я встречал при оптимизации ситуацию, когда компилятор просто выкидывает переменную (в силу индукции, т.е. создания отдельной переменной, причем часто в регистрах процессора - читай выше).
И вот в ситуации:
i:=0;
repeat
...
используем переменную i
...
until ...
компилятор говорит, что присвоение нуля никогда не происходит, потому как далее не используется в силу того, что внутри цикла переменная i - это не та же самая переменная, что была до цикла (и будет после)!
Советую поразмыслить над этим, потому как такие ситуации редко встречаются, трудно сходу подобрать пример.
Rooman (2002-03-20 12:38:00) [12]такое же сообщение иногда ( не всегдаестественно) появляется тогда, когда компилятор переделал ваш код так, что ваша переменная ему вообще не понадобилась! Именно про этуситуацию я вел речь выше, потому как часто с ней сталкивался.
Rooman (2002-03-20 12:34:00) [13]Внук: компилятор в твоем примере говорит следующую фразу:
Value (значение) assigned (присваемое) to "i" never used (никогда не было задействовано - в скомпилированном коде).
Что непонятно?
Rooman (2002-03-20 12:24:00) [14]Внук, в этом случае компилятор просто выкинул твою строку. Это тоже не страшно, как и в случае использования переменной внутри регистров. Ну не надо, блин, присваивать сначало одно, а потом другое - это неэффективно - говорит компилятор.
Rooman (2002-03-20 12:18:00) [15]переменные иногда хранятся прямо в регистрах процессора. См. Using Delphi:
The $O directive controls code optimization. In the {$O+} state, the compiler performs a number of code optimizations, such as placing variables in CPU registers ( размещение переменных в регистрах процессора - т.е. не в ОЗУ), eliminating common subexpressions ( реструктуризация сложных математических выражений в простые), and generating induction variables( создание индукционных переменных). In the {$O-} state, all such optimizations are disabled.
Other than for certain debugging situations, you should never have a need to turn optimizations off. All optimizations performed by Delphi"s Object Pascal compiler are guaranteed not to alter the meaning of a program ( не гарантирует эквивалентность работы вашего кода и кода оптимизированного). In other words, Delphi performs no "unsafe" optimizations that require special awareness by the programmer( другими словами, оптимизация приводит к изменению логики работы исходного алгоритма, но не к изменению его результатов).
Внук (2002-03-20 12:13:00) [16]>>Rooman (20.03.02 12:03)
Все, ухожу в монастырь. Пишите код
var i:integer;
i:=0;
i:=1;
далее следует жутко навороченный код, где переменная i используется в полный рост (строк 20000 со страшной логикой, не позволяющей засунуть эту переменную в регистр) - сами придумайте на свое усмотрение.
На строке i:=0; Вы гарантированно получате пресловутое предупреждение. Есть еще вопросы ?
Rooman (2002-03-20 12:03:00) [17]Еще раз утверждаю - именно не выделялась! Не верите - смотрите дизассемблер кода (надеюсь не надо объяснять как это сделать:)
Внук (2002-03-20 11:55:00) [18]"В данном случае компилятор говорит, что память под переменную при компиляции не выделялась"
Народ, вы что, всерьез это пишите??? Да ничего подобного. Выделение или невыделение памяти имеет к этому только косвенное отношение (как частный случай). Да если нельзя на строку с какой-то переменной поставить точку останова, неужто под нее память не выделялась??? На эту строку нельзя в силу оптимизации, на другую строку с этой же переменной можно, так что - память на статическую переменную то выделяется, то конфискуется, что ли? Я уже устал объяснять. Скоро эту ветку в "Потрепаться" перенесут :((
Внук (2002-03-20 11:38:00) [19]>>Rooman (20.03.02 11:19)
Согласен. Но это не противоречит всему ранее сказанному мной. Я утверждаю, что обсуждаемое здесь предупреждение обоснованно появляется даже в тех случаях, когда для переменной выделена память в виртуальном ОЗУ в конечном коде программы. Одно другому не мешает. И появление этого сообщения всегда свидетельствует о кривости кода, а это не есть хорошо (хотя и не страшно, иначе бы это был Error).
Alx2 (2002-03-20 11:38:00) [20]>что память под переменную при компиляции не выделялась
Скорее, исполняющий код не сгенерировался