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

Вниз

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

 
Внук   (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.6 MB
Время: 0.006 c
1-163
Max
2002-03-22 08:32
2002.04.01
Delphi 5 + W2k


4-366
JAndrey
2002-01-31 01:18
2002.04.01
Как сделать автозапуск при загрузке?


1-212
serg
2002-03-20 13:02
2002.04.01
TClass из ClassName


1-191
Smok_er
2002-03-19 02:17
2002.04.01
Строковой парсер


4-360
sdn
2002-02-01 19:15
2002.04.01
Как создать форму, похожую на ICQ





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