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

Вниз

Value assigned to   Найти похожие ветки 

 
Gluka   (2002-03-14 02:18) [0]

Что это за фигня, и как с этим бороться!!!


 
Lego   (2002-03-14 02:26) [1]

Ты где-то в var объявил об этой A и она просто неиспользуетса... либо если и используетса то не так как ожидал этого твой Делфи


 
~Sergius   (2002-03-14 02:57) [2]

Ко второй части вопроса ("как с этим бороться") -- выключается опция показывать Warnings


 
Suntechnic   (2002-03-14 03:20) [3]

>~Sergius (14.03.02 02:57)
>выключается опция показывать Warnings

Обычно это устраняется путём удаления "лишней" переменной, но кто во что горазд конечно...


 
~Sergius   (2002-03-14 04:06) [4]

2 Suntechnic ©
В который раз меня подводит привычка не ставить смайлы после шутки


 
Suntechnic   (2002-03-14 04:14) [5]

>~Sergius (14.03.02 04:06)
:)


 
Gluka   (2002-03-14 04:21) [6]

program g1;

uses ??;

var
a: integer;
begin
a:=0;
...
...
Value assigned to "A" never used
Почему!?!?!?


 
Suntechnic   (2002-03-14 04:32) [7]

>Gluka © (14.03.02 04:21)
А ты покажи место, где у тебя переменная a используется? Если такового нет, то что ты тогда от компилятора хочешь?


 
Lego   (2002-03-14 06:41) [8]

У тебя переменная
1. объявлена.
2. приравнена 0.
3. но не используется :)


 
stub   (2002-03-14 07:39) [9]

get focus on your messages window (where compiler collects its messages) and press F1 on selected error. you"ll get description on error from borland help.
enjoy.


 
Song   (2002-03-14 08:32) [10]

Кстати компилятор иногда ошибается насчёт подобного сообщения.

Хотел сначала привести пример такой ошибки, но думаю он (пример в смысле) строчек на 30, думаю не интересно будет его рассматривать другим. Компилятор легко вывести из толку.



 
drpass   (2002-03-14 10:19) [11]

>Gluka
А что тебя напрягает? Это ведь не ошибка, а предупреждение. Компилятор видит совершенно бесполезное присваивание (потому что ты действительно не используешь присвоенное значение), и считает своим долгом предупредить тебя - вдруг ты забыл дописать какую-нибудь команду. Если же тебе не нравятся такие предупреждения, ты можешь их отключить на вкладке Project Options->Compiler


 
Anatoly Podgoretsky   (2002-03-14 22:53) [12]

Лучше всего пирслушать к компилятору и использовать, а иначе зачем оно тебе нужно?

Song © (14.03.02 08:32)
А ты давай приведи, вдруг компилятор прав.


 
Malder   (2002-03-14 23:12) [13]

Anatoly Podgoretsky, компилятор действительно ошибается. И действительно трудно привести пример. У меня это было с каким-то компонентом. Он всегда писал S1 not used. Хотя S1 еще как юзалась...


 
Anatoly Podgoretsky   (2002-03-14 23:25) [14]

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


 
Shirson   (2002-03-15 07:54) [15]

Компилятор прав.
a:=0; это не использование переменной. Использование переменной это c:=b+a; Или for a:=0 to 100 do...
Попробуй выкинуть из свой процедуры декларацию этой переменной, убери из тела a:=0 и запусти программу. Что-нибудь неработает? :)


 
Внук   (2002-03-15 09:27) [16]

А мне бы тоже хотелось увидеть пример кода. Компилятор действительно иногда выводит "лишние" предупреждения, но не этого типа (насчет неинициализированной переменной бывает). Предупреждение на использование переменной достаточно легко проверить - компилятор всего лишь ищет обращения к данному участку памяти на чтение - оно либо есть, либо нет. По крайней мере, в моей практике (и моих коллег) случая ошибочного вывода именно этого предупреждения не было.


 
Sergey13   (2002-03-15 09:52) [17]

У меня тоже так бывало. Ругалось на неиспользование, при явном использовании переменной. Но как то эпизодически (то есть, то нет, и не каждый день) и "лечилось" повторной компиляцией. Вот так просто. Скомпилил раз - получил, скомпилил второй - пропало. Может с первого раза не понимал 8-) А отключать варнинги не стОит - иногда дело говорит.


 
Shirson   (2002-03-15 10:10) [18]

>Внук © (15.03.02 09:27)
А мне бы тоже хотелось увидеть пример кода. Компилятор действительно иногда выводит "лишние" предупреждения, но не этого типа (насчет неинициализированной переменной бывает).
---

Есть такое. Это когда объявляешь переменную и используешь её значение без предварительной инициализации. Что называется на свой страх и риск - компилятор за последствия ответственности не несет ;)


 
MAxiMum   (2002-03-15 10:16) [19]

Беда-то ещё в том, что компилятор ещё и выкинет строки кода с неиспользованной переменной (посмотрите на левую часть редактора с точками).
КОДА! КОДА! КОДА! КОДА! КОДА! КОДА! КОДА! КОДА! КОДА! КОДА! КОДА!


 
Sergey13   (2002-03-15 10:52) [20]

Опять полез в Делфу и получилось

procedure TForm12.FormShow(Sender: TObject);
var i,k,ls, vch,vcho:integer;
....
бла-бла-бла
....
vch:=1;
vcho:=1;
for i:=1 to ls do
begin
c:=copy(s,i,1);
if pos(c,"0123456789.,")>0 then st:=st+c
else
begin
if c="(" then vch:=1 else
if c="*" then vch:=2 else
if c="/" then vch:=3 else vch:=0;
if vch=1 then k:=k+1;
.....
бла-бла-бла
.....
Выдало - Value assigned to "vch" never used
При повторной компиляции исчезло.


 
Внук   (2002-03-15 10:53) [21]

>>Shirson ©
Я имел в виду немного другое, то есть действительно "лишние" предупреждения. Например, условный оператор, где переменная инициализируется только в одной ветке, а выполнению другой ветки невозможно по логике программы (пока недописанной). Вот так:

...
var i:byte;
...

procedure First;
begin
i:=1;
...
end;

procedure Second;
var ААА:integer;
begin
if i=1 then
begin
AAA:=1;
...
end
else
begin
...
end;
ShowMessage(IntToStr(AAA));
end;

Код набирал прямо здесь, но, думаю, смысл понятен


 
Внук   (2002-03-15 11:00) [22]

>>Sergey13 ©
Так ведь и правильно. Присвоение vch:=1; в самом начале бессмысленно, так как потом эта переменная в ЛЮБОМ случае переприсваивается.
"При повторной компиляции исчезло." :)) А если сделать Build All - появится снова.



 
Внук   (2002-03-15 11:09) [23]

Да, к коду в сообщении Внук © (15.03.02 10:53) нужно добавить что-то вроде
procedure Form1.OnCreate ...
begin
First;
Second;
end;


 
Sergey13   (2002-03-15 11:17) [24]

>Внук © (15.03.02 11:00)
Да ты прав, спасибо. Что то я это дело прошляпил, и покатил бочку на Делфу. Каюсь.


 
Anatoly Podgoretsky   (2002-03-15 21:47) [25]

Sergey13 © (15.03.02 10:52)
Говорили же прислушайся к компилятору, первое значение не используется НИКОГДА

Внук © (15.03.02 10:53)
Ну тут две проблемы.
1. компилятор одно проходный, он не может знать что переменная модет быть использован в другой процедуре, а может быть и нет, например по рпичине исключения.

2. переменная ААА может быть неинициализирована.

То есть оба примера неудовлетворительные.


 
Song   (2002-03-16 11:09) [26]

2Anatoly Podgoretsky © (14.03.02 22:53)
Извиняюсь, что раньше не смог, только приехал.
Пожалуйста, выдаёт что переменная Flag никогда не используется:


Flag:=False;
With Strg Do
With TreeView.Items Do
For t:=1 to RowCount-1 Do
Begin
Node:=TreeView.Items[0];
Repeat
try
IF Pos(Cells[IndexNo,t],Node.Text)>0 then
IF Pos("ingoing",S)>0 then
Begin
.....
Flag:=True;
End Else
Begin

......
Flag:=True;
End;

IF Node.Text="Другие документы" then NodeSafe:=Node;
Node:=Node.GetNextSibling;

except
IF not Flag then
Begin
.....
Flag:=True;
End;
Break;
end;
Until False;
End;



 
Внук   (2002-03-18 17:20) [27]

>>Song ©
А Вы считаете, что используется? Если код действительно таков, как здесь, можете смело выкидывать эту переменную Flag. Выход из цикла возможен только по Exception, где Flag будет всегда true. В теле цикла значение Flag не используется. Или я чего-то не понял?


 
Внук   (2002-03-18 17:55) [28]

>>Song ©
Торможу, однако. Нельзя Flag выкидывать, от него зависит обработка Exception. Только вот хотите верьте, хотите - нет, но этот код у меня (Delphi5) не выдал на переменную Flag никаких предупреждений. Может быть, дело в том, что стоит вместо ... ?


 
Song   (2002-03-19 08:59) [29]

2Внук © (18.03.02 17:55)
А у меня выводит :(( Я ж говорю, компилятор запутался...
Нет, вместо ... там ничего такого нет.
Кстати отрывок выкусил из программы некорректно.
Строка Flag:=False; стоит перед Repeat, т.е.:
.....

For t:=1 to RowCount-1 Do
Begin
Node:=TreeView.Items[0];
Flag:=False;
Repeat
try
IF Pos(Cells[Ind

...

Но это ничего не меняет. Предупреждение по прежнему не должно выдаваться.


 
ao1973   (2002-03-19 09:49) [30]

Удалено модератором


 
Song   (2002-03-19 09:55) [31]

2ao1973 (19.03.02 09:49)
Какой у Вас вопрос? Почему сразу в обидки?


 
keg   (2002-03-19 10:16) [32]

в показаном примере компилятор правильно предупреждает. В первой строке ты присваиваешь ему False и далее (в пропущенной строке) опять делаешь присваивание, а между ними Flag не используется, значит первое присваивание не нужно - его можно вырезать. Ну и в самом конце, в Exception опять делаешь присваивание, а после (до конца процедуры) Flag не используется, стало быть - какая разница, какое значение будет иметь Flag после выхода из цикла?


 
Rooman   (2002-03-19 10:36) [33]

Так, господа программисты!
Разрешаю вашу проблему раз и навсегда!

1.Компилятор компилит проект с ОПТИМИЗАЦИЕЙ кода (т.е. ваш код он преобразует оптимально - смотрите ДИЗАССЕМБЛЕР вашего кода), если включена опция ОПТИМИЗАЦИИ кода (см. свойства проекта).
Что это значит? Это значит, что под некоторые ЛОКАЛЬНЫЕ переменные место в ПАМЯТИ не резервируется, т.е. код оптимизируется так, что все операции по ЭТОЙ ПЕРЕМЕННОЙ происходят внутри РЕГИСТРОВ ПРОЦЕССОРА. Пример:

var a,b:integer;
...
a:=1;
b:=a;
...

компилится так:

mov eax,1 ; eax - регистр процессора
mov b,eax
...

и компилятор выдает предупреждение "Переменная a никогда не используется".

По большому счету - это даже хорошо, т.к. работает максимально БЫСТРО (без обращения к памяти).

2. Простое присваивание без последующего использования переменной автоматически отметается компилятором ПРИ ВКЛЮЧЕННОЙ ОПТИМИЗАЦИИ (см. св-ва проекта).





 
Ray   (2002-03-19 10:46) [34]

2 Rooman. Все верное. Все приведенные выше кода страдают одной и тоже ошибкой, вернее не ошибкой а недопониманием или не внимательностью. идет присвоение к переменной в первый раз, и далее сколько бы кода небыло если из нее ничего не считывается и только присваивается то первое присваивание совершенно ненужно. Вот компилятор и предупреждает. Легче всего понят это таким образом. Берем код. кдаляем строки где нет этой переменной и после чего смотри что остается?

Flag:=False;
Flag:=True;


 
RedWood   (2002-03-19 10:54) [35]

Всем привет !

>Кстати отрывок выкусил из программы некорректно.

>Строка Flag:=False; стоит перед Repeat, т.е.:
.....
Flag:=False;
With Strg Do
With TreeView.Items Do
For t:=1 to RowCount-1 Do
Begin
Node:=TreeView.Items[0];
Flag:=False;
Repeat

получается что предупреждение дает на первое присваивание Flag:=False; т.к. в цикле FOR все-равно переменная переопределяется. Естественно это справедливо, если переменная не используется дальше в процедуре.
кстати, предепреждение на какую строку дает ?


 
keg   (2002-03-19 11:17) [36]

2 RedWood. щелкни два раза на предупреждении и тебе покажет нужную строку.


 
Song   (2002-03-19 11:32) [37]

2RedWood:
Я ошибся при постинге сюда. Переменная Flag стоит перед Repeat и не стоит перед With.

Я понимаю сообщение так: "Переменная была объявлена, но не использовалась". Покажите мне любой путь внутри данного отрывка пусть даже с исключением, где бы строка, работающая с Flag не произошла.


 
Drex   (2002-03-19 12:35) [38]

А как вам этот кусок? Тут тоже не используется
i:=0;
CardByte:=0;
Repeat
Byte10:=0;
Bit:=0;
Repeat
i:=CardByte*8+Bit;
Case Bit Of {Перевод из двоичного в десятичное}
0:Byte10:=Byte10+Current[i]*128;
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;
Until Bit=8;


 
Внук   (2002-03-19 13:35) [39]

>>Song c (19.03.02 09:55) "Но это ничего не меняет. Предупреждение по прежнему не должно выдаваться."
Очень даже меняет :) Теперь и у меня выдает предупреждение на Flag:=True в приведенном ниже фрагменте:
...
Except
IF not Flag then
Begin
Flag:=True;
...
End;
Break;
end;
...
Ну и правильно, выход из цикла возможен только по Exception, при этом выполняется Flag:=True, а сразу же в следующей итерации внешнего цикла Flag:=False.
Собственно, на это и выдается предупреждение. Следует удалить из обработчика исключения присвоение флага. Компилятор прав.
Повторяю - данное предупреждение выдается, если между двумя обращениями к переменной на запись не было ни одного обращения к ней на чтение.
"Я понимаю сообщение так: "Переменная была объявлена, но не использовалась". - Сообщение понимать нужно так (буквально): переменной было присвоено значение, которое в дальнейшем не используется, то есть можно было его и не присваивать.
>>keg (19.03.02 10:16) См. Внук c (18.03.02 17:55) "Нельзя Flag выкидывать, от него зависит обработка Exception" - для старого фрагмента кода это так.
>>Ray c (19.03.02 10:46) Смею заметить, не все так просто. Хотя Rooman, конечно, прав.
>>All
Все, что я пытаюсь здесь доказать - это то, что предупреждение именно данного типа НИКОГДА не выводится зря. Но зачастую его можно игнорировать :)))


 
Внук   (2002-03-19 13:55) [40]

>>Drex (19.03.02 12:35)
То же самое. Если Вы сумеете объяснить компилятору, зачем Вам первая строка i:=0 (мне это обосновать не удалось), он больше никогда не будет выдавать Вам предупреждение :)


 
Анонимщик   (2002-03-19 15:44) [41]

Чем вы занимаетесь? Компилятор компилирует и оптимизирует. Нет у него в конечном коде вашей переменной, вот и пишет. Ясно?


 
Внук   (2002-03-19 16:14) [42]

>>Анонимщик © (19.03.02 15:44)
И зачем он это пишет? Для себя самого, или пообщаться хочет? Вопрос в том, когда появляются эти сообщения, и как их избежать. Тем более что во всех вышеперечисленных примерах переменные, на которые выданы предупреждения, в коде ПРИСУТСТВУЮТ в полный рост. А вот то, что большинство "крутых программистов" (никого из участников ветки в виду не имею и обидеть не хочу) не читают этих сообщений или не понимают их смысла - это факт.


 
deleon   (2002-03-19 16:29) [43]

Однажды у меня компилятор в одной абсолютно правильной функции объекта писал: "Internal Error xxxx" не помогала ни перезагрузка IDE, ни железа. В общем поменял местами эту функцию с соседней и все сразу компилятору понравилось! Но это было только один раз! Сколько раз я уже ругался на Delphi, но поковырявшись всегда оказывалось что это мои баги, так что можно сказать что в 99,8 % компилятор прав :)


 
Donal_Graeme   (2002-03-19 16:38) [44]

вот насчёт Internal Errors это отдельная история :-)) В хэлпе сказано, что такие ошибки никогда не должны появляться. Тем не менее они появляются :-) В некоторых случаях удаётся понять, что именно не понравилось компилятору (мне один раз удалось, но я не помню ни кода ошибки, ни причины).


 
Анонимщик   (2002-03-19 18:28) [45]

Внук.
В коде они, может, и присутствуют, да компилятор их использовать не видит смысла, потому как они ни для чего не нужны. Каким образом именно этот компилятор решает, что именно эта переменная - лишняя и о ней можно не беспокоиться, судить не стану, для этого нужно его изнутри знать. Но кое-что предположить, конечно, можно. А присутствуют ли эти переменные в том, во что компилятор превратит ваш паскальный код (это, естественно, исполнимый код), это как раз и самое главное для понимания, откуда такие предупреждения берутся. Посмотри в отладчике на значение той переменной, на которую компилятор что-то плохое говорит, тогда и дело яснее станет.


 
Anatoly Podgoretsky   (2002-03-19 20:46) [46]

Что бы конкретно говорить, надо что бы предсталенный код можно было повторить, путем простого копированич в редактор, а оторваныые коды, к тому же с ошибками при коприовании мало чего дают, пока не приведен ни один пример, который можно было бы воспроизвести. Это говорит о том, что если компьютере и ошибается, то крайне редко. Но даже если он и ошибается, то есть смысл задуматься почему, может сделана неудачная конструкция, слишком сложная, что и компилятор не смог ее понять.


 
Drex   (2002-03-20 05:46) [47]

>>Внук
И правда, пытался объянить, да только не получилось ничего, ;-) иногда такую ерунду напишешь, аж самому смешно становится. Это видать когда процедуру отлаживал некоторые ранее нужные вещи перестали быть нужными... Спасибо


 
vl_chel   (2002-03-20 08:13) [48]

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


 
vl_chel   (2002-03-20 08:24) [49]

>>Drex в написанном вами коде переменные CardByte и i не мужны
i:=0; << Смысл??
CardByte:=0;
Repeat << к чему это относится?
Byte10:=0;
Bit:=0;
Repeat
i:=CardByte*8+Bit; << CardByte = 0 Смысл??


Case Bit Of {Перевод из двоичного в десятичное}
0:Byte10:=Byte10+Current[i]*128;<<Меняем во всех строчках I на 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;



 
Внук   (2002-03-20 10:00) [50]

>>Анонимщик © (19.03.02 18:28)
Повторяю большими буквами: предупреждение означает не то, что ПЕРЕМЕННАЯ не используется, а то, что текущее ЗНАЧЕНИЕ ПЕРЕМЕННОЙ не используется. Почувствуйте же разницу и читайте сообщения буквально так, как они пишутся. Неправильный перевод приводит к неправильной интерпретации. Не решает компилятор, что переменная лишняя, он лишь сообщает, что значение, присвоенное переменной, сразу же (без какого-либо использования этого значения) затирается другим значением.


 
Rooman   (2002-03-20 11:19) [51]

Еще раз жирно: переменная не используется только тогда, когда под нее не выделена память в ОЗУ. Т.е. ее значение как минимум гуляет в регистрах. А это, как правило, всегда хорошо!


 
Rooman   (2002-03-20 11:29) [52]

Warnings - это не ошибки, если вы читали хотябы элементарный хелп к дельфе. Если бы это было ошибкой - хрен бы вам скомпилился, а не программа! В данном случае компилятор говорит, что память под переменную при компиляции не выделялась, т.е. нельзя поставить брейкпоинт на ее значение, например, или нельзя дебагером посмотреть ее значение на этапе выполнения. Вот и все! В чем проблемы то?


 
Внук   (2002-03-20 11:38) [53]

>>Rooman (20.03.02 11:19)
Согласен. Но это не противоречит всему ранее сказанному мной. Я утверждаю, что обсуждаемое здесь предупреждение обоснованно появляется даже в тех случаях, когда для переменной выделена память в виртуальном ОЗУ в конечном коде программы. Одно другому не мешает. И появление этого сообщения всегда свидетельствует о кривости кода, а это не есть хорошо (хотя и не страшно, иначе бы это был Error).


 
Alx2   (2002-03-20 11:38) [54]

>что память под переменную при компиляции не выделялась
Скорее, исполняющий код не сгенерировался


 
Внук   (2002-03-20 11:55) [55]

"В данном случае компилятор говорит, что память под переменную при компиляции не выделялась"
Народ, вы что, всерьез это пишите??? Да ничего подобного. Выделение или невыделение памяти имеет к этому только косвенное отношение (как частный случай). Да если нельзя на строку с какой-то переменной поставить точку останова, неужто под нее память не выделялась??? На эту строку нельзя в силу оптимизации, на другую строку с этой же переменной можно, так что - память на статическую переменную то выделяется, то конфискуется, что ли? Я уже устал объяснять. Скоро эту ветку в "Потрепаться" перенесут :((


 
Rooman   (2002-03-20 12:03) [56]

Еще раз утверждаю - именно не выделялась! Не верите - смотрите дизассемблер кода (надеюсь не надо объяснять как это сделать:)


 
Внук   (2002-03-20 12:13) [57]

>>Rooman (20.03.02 12:03)
Все, ухожу в монастырь. Пишите код
var i:integer;
i:=0;
i:=1;
далее следует жутко навороченный код, где переменная i используется в полный рост (строк 20000 со страшной логикой, не позволяющей засунуть эту переменную в регистр) - сами придумайте на свое усмотрение.

На строке i:=0; Вы гарантированно получате пресловутое предупреждение. Есть еще вопросы ?


 
Rooman   (2002-03-20 12:18) [58]

переменные иногда хранятся прямо в регистрах процессора. См. 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( другими словами, оптимизация приводит к изменению логики работы исходного алгоритма, но не к изменению его результатов).


 
Rooman   (2002-03-20 12:24) [59]

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


 
Rooman   (2002-03-20 12:34) [60]

Внук: компилятор в твоем примере говорит следующую фразу:

Value (значение) assigned (присваемое) to "i" never used (никогда не было задействовано - в скомпилированном коде).

Что непонятно?


 
Rooman   (2002-03-20 12:38) [61]

такое же сообщение иногда ( не всегда естественно) появляется тогда, когда компилятор переделал ваш код так, что ваша переменная ему вообще не понадобилась! Именно про эту ситуацию я вел речь выше, потому как часто с ней сталкивался.


 
Rooman   (2002-03-20 13:16) [62]

По поводу индукционных переменных:

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 13:26) [63]

Короче,совет тому, кто задал вопрос - отключи оптимизацию в опциях проекта. Тогда все скомпилируется именно так, как ты написал в своем коде. Но лучше этого не делать и вообще забить (проверить код свой, т.е.):)))


 
Rooman   (2002-03-20 13:34) [64]

Внук: финальный аккорд тебе - то, о чем ты говоришь - это как раз следствие того, о чем говорю я. Потому что наиболее часто встречающаяся ситуация при оптимизации - размещение индукционных переменных в регистрах процессора приводит к тому, что компилятор вынужден выкинуть первую строчку кода:
i:=0;
i:=1;
так как создание индукционной переменной в этой строчке не имеет смысла - она не используется далее.

Обмозгуй это, и ты меня поймешь.


 
Rooman   (2002-03-20 13:40) [65]

Общий совет: разделите внутри себя понятия: код на паскале и код на ассемблере. Процессору по барабану, переменную вы задали, или константу, у процессора есть регистры, доступная для него память в данном процессе (вирт.машина) с разными правами доступа (ч/з) и стек. Все регистры и все данные, с которыми оперирует процессор - трех типов: QWORD,DWORD,WORD и BYTE.
Всё! Больше ничего.


 
Внук   (2002-03-20 14:16) [66]

>>Rooman
Мне это объяснять не нужно :) Регистровые переменные в C мной использовались, еще когда DOS был нам единственной надеждой и опорой. То, что одна и та же переменная в тексте программы на Паскале может быть по разному представлена на протяжении своего использования в коде на ассемблере, это факт. Но для начинающего (или не очень) программиста, который видит лишь исходный текст своей программы - это одно и тоже. Поэтому я и рассуждаю с точки зрения языка высокого уровня. Судя по репликам (см. самое начало), довольно многие неправильно понимают смысл сообщения, что переменная не используется вообще. Лишь промежуточное значение этой переменной не используется. Теперь мы кажется начали говорить об одном и том же :)
Сейчас моя очередь давать совет вопрошающему: не отключайте оптимизацию и не игнорируйте предупреждения, поскольку они свидетельствуют о том, что Ваш алгоритм настолько неэффективен, что это видно даже компилятору и он берется его грубо править для Вас. Это уже какой-то полуфабрикат получается :)


 
Rooman   (2002-03-20 18:39) [67]

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


 
Rooman   (2002-03-20 18:54) [68]

А алгоритм может быть эффективным. Даже очень. Одно с другим не коррелирует:)


 
Drex   (2002-03-21 12:50) [69]

>>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 для внешнего цикла




 
Stratos   (2002-03-21 14:16) [70]

К слову о внутренних ошибках:
У меня выдавалась такая после того, как в процедуре написал цикл forв нем case ofc break. После удаления цикла (break остался) появилась ошибка. По идее, компилятор должен был ругнуться по-хорошему. Может он в больших проектах запутывается.

В общем, едиственное надежное средство отладки - шаманский бубен 8)


 
fenics   (2002-03-21 18:42) [71]

Бедный Gkuka! До чего может ловести беседа десятка програмистов!
Через неделю о его вопросе уже и невспоминали!


 
fenics   (2002-03-21 18:42) [72]

Бедный Gluka! До чего может ловести беседа десятка програмистов!
Через неделю о его вопросе уже и невспоминали!



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

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

Наверх





Память: 0.65 MB
Время: 0.006 c
14-294
Fellomena
2002-02-13 15:53
2002.04.01
Помяните меня в своих молитвах - в ближайшее время меня обрекли на Фортран =(


14-300
fliz
2002-02-19 13:00
2002.04.01
подскажите, откуда можно скачать нормальную версию Internet Explorer 6 ?


4-345
Di_wind
2002-01-30 20:20
2002.04.01
TerminateProccess


1-126
Sound
2002-03-19 01:38
2002.04.01
Какой компонент юзать?


7-324
Nomad
2001-12-29 15:14
2002.04.01
Как в NT-ях разрешить программе редактировать реестр текущего пользователя?





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