主页
Top.Mail.Ru Yandeks.Metrika
论坛:“主要”;
当前存档:2002.04.01;
下载:[xml.tar.bz2];

向下

分配给的值 找到类似的分支


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:整数;
开始
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.
享受。



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]

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

歌曲©(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]

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

程序TForm12.FormShow(发件人:TObject);
var i,k,ls, VCH,vcho:integer;
....
等等等等
....
vch:=1;
vcho:=1;
for i:=1 to ls do
开始
c:=copy(s,i,1);
if pos(c,"0123456789.,")>0 then st:=st+c
其他
开始
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;
开始
i:= 1;
...
结束;

procedure Second;
var ААА:integer;
开始
如果我= 1那么
开始
AAA:=1;
...
结束
其他
开始
...
结束;
ShowMessage(IntToStr(AAA));
结束;

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



Внук   (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 ...
开始
首先;
Second;
结束;



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)
А у меня выводит :(( Я ж говорю, компилятор запутался...
Нет, вместо ... там ничего такого нет.
Кстати отрывок выкусил из программы некорректно.
标志:=假; стоит перед 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, т.е.:
.....
标志:=假;
With Strg Do
With TreeView.Items Do
对于t:= 1到RowCount-1 Do
开始
Node:=TreeView.Items[0];
标志:=假;
重复新密码

получается что предупреждение дает на первое присваивание 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;
重复新密码
Byte10:=0;
Bit:=0;
重复新密码
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;
结束;
Bit:=Bit+1;
i:= i + 1;
Until Bit=8;



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

>>Song c (19.03.02 09:55) "Но это ничего не меняет. Предупреждение по прежнему не должно выдаваться."
Очень даже меняет :) Теперь и у меня выдает предупреждение на Flag:=True в приведенном ниже фрагменте:
...

IF not Flag then
开始
Flag:=True;
...
结束;
打破;
结束;
...
Ну и правильно, выход из цикла возможен только по 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, конечно, прав.
>>全部
Все, что я пытаюсь здесь доказать - это то, что предупреждение именно данного типа НИКОГДА не выводится зря. Но зачастую его можно игнорировать :)))



Внук   (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]

有一个编译器在一个绝对正确的对象函数中写道:“内部错误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;
重复新密码
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;
结束;
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:整数;
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:整数;
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;
重复
...
используем переменную i
...
直到......

компилятор говорит, что присвоение нуля никогда не происходит, потому как далее не используется в силу того, что внутри цикла переменная 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;
重复新密码
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;
结束;
Bit:=Bit+1;
i:=i+1;<< зачем увеличивать I (грамотнее inc(I)) Учту, спасибо что без сарказма
Until Bit=8;

Здесь дет инкремент CardByte и Until для внешнего цикла





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

К слову о внутренних ошибках:
У меня выдавалась такая после того, как в процедуре написал цикл 在它 的情况下,c 打破. После удаления цикла (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.87 MB
时间:0.06 c
1-233
奥尔加
2002-03-18 16:24
2002.04.01
Outlook


3-23
amamed_3071
2002-03-05 08:17
2002.04.01
错误超时预期帮助


1-175
AERO
2002-03-19 16:54
2002.04.01
如何将价值从一个程序转移到另一个程序?


14-289
阿尔马斯
2002-02-15 15:01
2002.04.01
安装Delphi的问题


1-149
只是人
2002-03-22 00:46
2002.04.01
如何在TabSheet上创建一个备忘录





南非荷兰语 阿尔巴尼亚人 阿拉伯语 亚美尼亚 阿塞拜疆 巴斯克 白俄罗斯 保加利亚语 加泰罗尼亚 简体中文 中国(繁体) 克罗地亚 捷克 丹麦语 荷兰人 英语 爱沙尼亚语 菲律宾人 芬兰 法文
加利亚西语 格鲁吉亚语 德语 希腊语 海地克里奥尔语 希伯来语 印地语 匈牙利 北日耳曼语 印度尼西亚人 爱尔兰语 意大利语 日本性玩偶 韩语 拉脱维亚 立陶宛 马其顿 马来语 马耳他语 挪威语
波斯语 波兰语 葡萄牙语 罗马尼亚 俄语 塞尔维亚 斯洛伐克 斯洛文尼亚 西班牙语 斯瓦希里 瑞典语 泰国人 土耳其 乌克兰 乌尔都语 越南人 威尔士语 意第绪语 孟加拉 波斯尼亚
宿务 世界语 古吉拉特语 豪萨语 苗族 伊博 爪哇 卡纳达语 高棉 老挝 拉丁语 毛利 马拉 蒙古人 尼泊尔 旁遮普 索马里 泰米尔人 泰卢固语 约鲁巴语
祖鲁
英文 Французский Немецкий Итальянский Португальский 俄文 Испанский