Здравствуйте, Mystic, Вы писали:
T>>Указатели надо T>>1. всегда инициализировать нулем M>Хм... зачем? Указатели надо инициализировать перед использованием, как и все прочие переменные.
M>
M> P := nil; // Следуем непогрешимому правилу #1 и получаем хинт.
M> P := AllocMem(16);
M>
Кто тебе сказал, что выделение памяти будет в том же методе ?
T>>2. всегда ставить ассерт на !NULL при использование (как минимум) M>В зависимости от контекста. Если мы получили адрес локальной переменной, функции/процедуры, то зачем тут Assert?
А ты только с локальными переменными работаешь ? Все методы без аргументов ?
M>
M> P := @I;
M> P^ := 4; // А тут, имхо, Assert лишь загромоздит кода, коинтольное изнасилование в голову выходит...
M>
Ассерт тормозит дебаг и несильно.
M>Во-вторых, отлов нулевых указателей почти везде работает на ура и не несет большой проблемы. То ли свалится Assert, то ли свалится использующий оператор --- не вижу разницы. Б\'ольшая проблема --- использование поврежденных указателей.
Читай выделенное. Для этого и надо выполнять п.1 — инициализировать нулем.
T>>3. всегда проверять что куда присваиваешь M>Целиком и полностью за, но настаиваю на том, что данный пункт справедлив не только в отношении указателей
С укузателями особый случай. Потому как указатель на экземпляр класса это фактически указатель на методы.
T>>4. всегда затирать нулем если объект разрушен M>Возможны различные схемы. В некоторых случаях это бессмысленно. А когда ты не уверен в том, что указателем никто больше не воспользется, то совет разумен.
Увереным вообще быть нельзя. Сейчас по проекту, который был заморожен два года назад, приходится много лишнего геморроя отлаживать потому как разрабы прежние считали что "В некоторых случаях это бессмысленно".
M>Тут я совсем не понял. Что значит --- за ними следить? Их надо различать в ряде случаев. Но если метод принимает указатель, то в большинстве случаев безразлично, на что он указывает.
Это я и имел в виду. Если метод модифицирует содержимое по указателю, надо различать, что передаешь в этот метод. Вот такие дела.
T>>6. осторожно пользоваться адресной арифметикой M>Чем отличается от п. 3?
Тем, что присваиваение в одном методе, а использование в другом.
T>>7. осторожно пользоваться приведением типа M>Тавтология с п. 3.
Про паскаль речи не идет. Почитай про множественное наследование.
T>>Теперь про управление памятью T>>8. следить за тем T>> а. кто выделяет память T>> б. кто освобождает память M>Иногда это проблема. Иногда это тривиально. К тому же указатели это не обязательно динамическая память.
Управление памятью означает чт именно динамическая память. Проблема как раз в том, что "Иногда это проблема. Иногда это тривиально."
T>>9. Проверять неявное выделение памяти M>В смысле, проверять? Вот в .NET вся динамическая память выделяется неявно, как мне ее прикажете проверять???
Мы вовсе не про дотнет. В c/с++ есть кучка мест, где память выделяется неявно. Макросы, функции глупые, структуры, конструкторы, операторы.
T>>Слишком много правил, не правда ли ? M>Все с легкостью выводимо из понимания архитектуры. К тому же приведенные правила не имеют догматичный характер...
Легко. К сожалению сишком мало программистов которые это все это соблюдают.
Здравствуйте, Tanker, Вы писали:
T>Здравствуйте, Mystic, Вы писали:
T>>>1. всегда инициализировать нулем M>>Хм... зачем? Указатели надо инициализировать перед использованием, как и все прочие переменные. T>Кто тебе сказал, что выделение памяти будет в том же методе ?
Минуточку, ты писал "указатели всегда надо инициализировать нулем". Я вполне допускаю существование случаев, когда указатели должны инициализироваться нулем.
T>>>2. всегда ставить ассерт на !NULL при использование (как минимум) M>>В зависимости от контекста. Если мы получили адрес локальной переменной, функции/процедуры, то зачем тут Assert? T>А ты только с локальными переменными работаешь ? Все методы без аргументов ? T>Ассерт тормозит дебаг и несильно.
Ну... насчет того, что тормозит отладка я не замечал. Во-вторых, ты писал "всегда". Я же не говорю, что такие Assert-ы надо исключить. Но в случае его отсутствия в Windows будет исключение, которое в большинстве случаев сгодится вмето Assert-а.
T>>>3. всегда проверять что куда присваиваешь M>>Целиком и полностью за, но настаиваю на том, что данный пункт справедлив не только в отношении указателей T>С укузателями особый случай. Потому как указатель на экземпляр класса это фактически указатель на методы.
А почему если указатели, то обязательно С++? Есть ассемблер и масса других языков. Кстати, стандарт С++ сообще подобными вещами не заморачивается, ты используешь особенности реализации. Может будем говорить о том, что надо не испольовать особенности реализации конкретного компилятора и бесбоязненно использовать указатели?
T>>>4. всегда затирать нулем если объект разрушен M>>Возможны различные схемы. В некоторых случаях это бессмысленно. А когда ты не уверен в том, что указателем никто больше не воспользется, то совет разумен. T>Увереным вообще быть нельзя. Сейчас по проекту, который был заморожен два года назад, приходится много лишнего геморроя отлаживать потому как разрабы прежние считали что "В некоторых случаях это бессмысленно".
Криво написать программу можно и без помощи указателей
T>>>7. осторожно пользоваться приведением типа M>>Тавтология с п. 3. T>Про паскаль речи не идет. Почитай про множественное наследование.
Мы про указатели или про C++?
T>>>9. Проверять неявное выделение памяти M>>В смысле, проверять? Вот в .NET вся динамическая память выделяется неявно, как мне ее прикажете проверять??? T>Мы вовсе не про дотнет. В c/с++ есть кучка мест, где память выделяется неявно. Макросы, функции глупые, структуры, конструкторы, операторы.
Мы про указатели или про C++?
Z>Интерпретаторы строят не на принципах формальных грамматик. Их строят на основе вычислительных моделей. Задумайтесь, чем отличается интерпретатор Scheme от интерпретатора Haskell. Грамматикой?
Да, этот вопрос потерял смысл без уточнения. В интерпретаторе 2 стадии — синтаксического разбора и собственно вычислений. Я имел ввиду первое, разумеется. Смысл второго действительно банален и может быть действительно кому-то интересен на начальном этапе.
А я вообще напирал на "механическую" сторону вопроса. Лично мне было бы неуютно и не интересно за компьютером, если бы я не понимал принципов его работы. А после того как начал понимать, можно уже и за Схему браться и за что угодно.
Здравствуйте, Mystic, Вы писали:
M>Минуточку, ты писал "указатели всегда надо инициализировать нулем". Я вполне допускаю существование случаев, когда указатели должны инициализироваться нулем.
Именно всегда. Т.к. ты не знаешь на момент разработки, что произойдет с кодом через некоторое время.
T>>>>2. всегда ставить ассерт на !NULL при использование (как минимум) M>>>В зависимости от контекста. Если мы получили адрес локальной переменной, функции/процедуры, то зачем тут Assert? T>>А ты только с локальными переменными работаешь ? Все методы без аргументов ? T>>Ассерт тормозит дебаг и несильно. M>Ну... насчет того, что тормозит отладка я не замечал. Во-вторых, ты писал "всегда". Я же не говорю, что такие Assert-ы надо исключить. Но в случае его отсутствия в Windows будет исключение, которое в большинстве случаев сгодится вмето Assert-а.
Исключение вылетит в самый неудобный момент, когда указатель ты передашь чурт-знает куда. Ассерт же указывает на ошибку сразу.
M>А почему если указатели, то обязательно С++? Есть ассемблер и масса других языков. Кстати, стандарт С++ сообще подобными вещами не заморачивается, ты используешь особенности реализации. Может будем говорить о том, что надо не испольовать особенности реализации конкретного компилятора и бесбоязненно использовать указатели?
Это не ко мне.
T>>Увереным вообще быть нельзя. Сейчас по проекту, который был заморожен два года назад, приходится много лишнего геморроя отлаживать потому как разрабы прежние считали что "В некоторых случаях это бессмысленно". M>Криво написать программу можно и без помощи указателей
Конечно. Но дело в том, что большинство багов на C/С++ — это именно указатели.
M>>>Тавтология с п. 3. T>>Про паскаль речи не идет. Почитай про множественное наследование. M>Мы про указатели или про C++?
Указатели "отдельно" не существуют. В с++ с ними свои проблемы. В паскале — свои. Я говорил только про С++. Не нравится — напиши как хорошо с указателями на паскале.
T>>Мы вовсе не про дотнет. В c/с++ есть кучка мест, где память выделяется неявно. Макросы, функции глупые, структуры, конструкторы, операторы. M>Мы про указатели или про C++?
Напишу еще разок — указатель без контекста это "сферический конь в вакууме".
В паскале свои проблемы — COM, WINAPI и тд.
Естественно, если ты пишешь программы не используя ни COM, ни WINAPI, то тебе и указатели не нужны. На нет и спроса нет.
P.S. Проблеммы c указателями встерчаются, как ни странно, именно там где эти самые указатели встречаются
Здравствуйте, Towiz, Вы писали:
O>>Ну как-то раз я пытался одной девушке объяснить, что такое указатели. Нет, даже двум! Оба раза провал
T>Нет, ну я одной девушке объяснил. Она даже поняла что такое связные списки. T>Потом мы поженились
Здравствуйте, Павел Кузнецов, Вы писали:
ПК>Mystic,
>> СГ> А я вот не понимаю в каком месте сложна Общая Теория Относительности, но встречал очень небольшое количество людей думающих также.
>> Бог с ней, ОТО... Вот квантовая механика...
ПК>Релятивистская
Товарищи, лучше проквантуйте ОТО. Вот тут мозги-то у вас и сплавятся.
Здравствуйте, vdimas, Вы писали:
V>В интерпретаторе 2 стадии — синтаксического разбора и собственно вычислений. Я имел ввиду первое, разумеется. Смысл второго действительно банален и может быть действительно кому-то интересен на начальном этапе.
Э... Я бы сказал, что смысл первого банален и может быть нтересен на начальном этапе.
Здравствуйте, Mystic, Вы писали:
M>Бывает. Плюс в мое время много самоучек. Одного моего знакомого учили Basic так: это PRINT, это LET, это INPUT. а до остального сам догадаешься В любом случае этому уделяют внимания меньше чем нужно.
Гм... А оказывается синтаксис я подзабыл уже...
[RSDN@Home][1.2.0][alpha][668]
[3лой человек вредит самому себе прежде, чем повредит другому. [Августин]]
dmz>Читаю в Джоэла, в который раз натыкаюсь упоминания на сложность указателей, вплоть до того, dmz>что он готов посвятить им отдельную часть мозга.
dmz>Не, ну я понимаю — функциональное программирование наверное штука сложная — монады там, то-сё. dmz>Но в каком месте сложны указатели-то? А? Не помню что бы хоть кто-то испытывал с ними какие-то dmz>проблемы, даже в школе.
А я вот встречаю людей, которые даже в Шарпе, где типа "не надо думать об указателях", пишут
потом не могут понять, почему у a1 изменилась улица.
Это чуть утрированный пример, но ситуация происходит именно такая. не понимают, почему ресурс которому дали Dispose() перестал быть доступен во всех объектах, которые на него ранее завели ссылки. Или почему в памяти все еще висит объект, который привязан через обработчик события.
Причем зачастую бывает что люди совсем неглупые.
Вот потому видимо, Джоел и выделяет это в отдельную область мозга. Что вроде бы ведь легко, а почему-то не у всех полчается...
Сложно ли иметь красивый почерк?
Сложно ли забросить мячик в корзинку с 3х метров?
Ну и самое главное — вот есть какие-то непонятные люди дальтоники. Типа не различают цвета. Ну не бред ли? Я вот понимаю математический анализ — это сложно — но отличить зеленый от голубого?? Какая проблема может быть? Даже в школе ни у кого нет проблем!
P.S.
Лично я помню, когда в школе изучал Паскаль, я просто не мог понять суть указателей. Все эти списки и прочая лабуда были мне белым шумом. Да, я мог сделать пример из учебника и посмотреть как он работает. Даже упражнения мог сделать, когда они были по полной аналогии. Но чуть в сторону — труба. А потом в какй-то момент наступило просто Просветление, иначе это не назвать. Я до сих пор помню этот момент — вся информация вдруг сложилась в стройную картину и я понял насколько это здорово и нужно! И уже не понимал, как же раньше это могло быть не понятно — ведь все так примитивно.. %)
Здравствуйте, Tanker, Вы писали:
T>Видишь ли, тут все сложно. С одной стороны когда играется слишком много (чистый c/с++ник) это одно. А совсем другое — когда совсем не играется — C#.
T>Я думаю играться надо в меру — С#/С++
Здравствуйте, dmz, Вы писали:
dmz>Читаю в Джоэла, в который раз натыкаюсь упоминания на сложность указателей, вплоть до того, dmz>что он готов посвятить им отдельную часть мозга.
dmz>Не, ну я понимаю — функциональное программирование наверное штука сложная — монады там, то-сё. dmz>Но в каком месте сложны указатели-то? А? Не помню что бы хоть кто-то испытывал с ними какие-то dmz>проблемы, даже в школе.
dmz>Может, у Джоэла были в детстве какие-то проблемы с указателями, которые травмировали нежную психику, dmz>а теперь он на всех это проецирует?
Суть указателей довольно проста, а вот использование может стать весьма утомительным.
Основным минусом использования указателей является их сильная зависимость от контекста.
Контекст пространства — указатель привязан к процессу,
использование указателя в другом процессе в общем случае небезопасно.
Контекст времени — в одном и том же процессе указатель валиден в течение некоторого интервала времени,
пока он указаывает на живой объект. Ни до, ни после, использование указателя небезопасно.
Указатель это один из видов ссылок (ссылки в обшем смысле) одних объектов на другие,
причем довольно опасный.
Плюсом указателей является их, видимо, самая высокая скорость разрешения в объект.
Так что указатель, с одной стороны — это просто адрес,
а с другой — это частный случай ссылок с определенными характеристиками,
которые нужно учитывать используя указатели.
m_n wrote: > Контекст пространства — указатель привязан к процессу, > использование указателя в другом процессе в общем случае небезопасно.
Кхм. Обращаться напрямую между процессами возможно вообще только в
особых случаях.
> Контекст времени — в одном и том же процессе указатель валиден в течение > некоторого интервала времени, > пока он указаывает на живой объект. Ни до, ни после, использование > указателя небезопасно.
Почему? Инициализируем указатель нулем при создании — и обращайся к нему
сколько хочешь, причем вполне безопасно.
> Указатель это один из видов ссылок (ссылки в обшем смысле) одних > объектов на другие, причем довольно опасный.
Отсюда подробнее.
Как для ссылок в общем случае определить адресную арифметику?
> Так что указатель, с одной стороны — это просто адрес, > а с другой — это частный случай ссылок с определенными характеристиками, > которые нужно учитывать используя указатели.
Скорее ссылки (в понимании CLR/JVM) — это частный случай указателей.
Здравствуйте, Cyberax, Вы писали:
C>m_n wrote: >> Контекст пространства — указатель привязан к процессу, >> использование указателя в другом процессе в общем случае небезопасно. C>Кхм. Обращаться напрямую между процессами возможно вообще только в C>особых случаях.
Использование указателя из другого процесса технически возможно,
так что нужно помнить чем грозит такое использование.
>> Контекст времени — в одном и том же процессе указатель валиден в течение >> некоторого интервала времени, >> пока он указаывает на живой объект. Ни до, ни после, использование >> указателя небезопасно. C>Почему? Инициализируем указатель нулем при создании — и обращайся к нему C> сколько хочешь, причем вполне безопасно.
Разумеется, Вы можете сделать использование указателей безопасным,
приложив дополнительные усилия, вот инициализация нулем — одно из них.
Проверка на нуль перед использованием или
отлов исключений при разыменовывании нулевых/невалидных указателей —
все это правила использования указателей.
Проблема в том, что правила использования указателей не следуют из их синтаксиса,
а держутся только на аккуратности/опыте разработчика.
А раз безопасность использования указателей контролируется человеком, а не компилятором,
значит использование указателей является небезопасным.
>> Указатель это один из видов ссылок (ссылки в обшем смысле) одних >> объектов на другие, причем довольно опасный. C>Отсюда подробнее.
Термин ссылка перегружен в этом абзаце, лучше вот так:
Указатель это один из видов реализации ассоциаций между объектами, причем довольно опасный.
Есть, по крайней мере, еще один вид реализации ассоциаций — это ассоциации по ключу.
Например, с объектом Заказ ассоциирован объект Клиент.
Как реализовать эту ассоциацию?
Можно через указатель на соответсвующий объект клиента.
А можно через ключ того же клиента.
Ключ более безопасный, но он более медленный при разрешении в объект.
У ключа отсутствует контекст пространства — ключ можно использовать в любом процессе.
Использование ключа частично следует из его синтаксиса —
ключ необходимо разрешать в объект перед использованием.
C>Как для ссылок в общем случае определить адресную арифметику?
>> Так что указатель, с одной стороны — это просто адрес, >> а с другой — это частный случай ссылок с определенными характеристиками, >> которые нужно учитывать используя указатели.
Все та же моя неточность:
Так что указатель, с одной стороны — это просто адрес,
а с другой — это вариант реализации ассоциаций с определенными характеристиками,
которые нужно учитывать используя указатели.
C>Скорее ссылки (в понимании CLR/JVM) — это частный случай указателей.
Согласен с Вами.
m_n wrote: > C>Кхм. Обращаться напрямую между процессами возможно вообще только в > C>особых случаях. > Использование указателя из другого процесса /технически возможно/, > так что нужно помнить чем грозит такое использование.
У твоего ассоциативного примера — тоже.
> C>Почему? Инициализируем указатель нулем при создании — и обращайся к нему > C> сколько хочешь, причем вполне безопасно. > Разумеется, Вы можете сделать использование указателей /безопасным/, > приложив дополнительные усилия, вот инициализация нулем — одно из них. > Проверка на нуль перед использованием или > отлов исключений при разыменовывании нулевых/невалидных указателей — > все это правила использования указателей.
А почему тогда в Java (языке со ссылками!) есть
NullPointerException?
> Указатель это один из видов реализации ассоциаций между объектами, > причем довольно опасный.
Уже лучше.
> Есть, по крайней мере, еще один вид реализации ассоциаций — это > ассоциации по ключу. > Например, с объектом Заказ ассоциирован объект Клиент. > Как реализовать эту ассоциацию? > Можно через указатель на соответсвующий объект клиента. > А можно через ключ того же клиента.
С теми же проблемами — а если по ключу будет лежать другой объект или
ничего не будет?