Здравствуйте, _FRED_, Вы писали:
_FR>Допустим, константного. Тут два варианта. Или "другой язык" понимает константность, но тогда неинтересно, либо не понимает. Тогда он её не видит и не может до неё доступиться. Не знает о ней и всё. И ничего страшного в этом нету.
Например, такой вариант — "другой язык" не понимает, что такое константа, и радостно пытается модифицировать эту переменную. После чего ВМ выдает ему исключением по мордасам.
Разве плохо?
_FR>Жизнеспособная, например, в рамках группы языков, поддерживающих константность. _FR> Этого более чем достаточно.
В том-то вся и проблема, что недостаточно. Никакого интеропа с внешним кодом не будет.
То есть для начала нужно перекомпилять (переписав) всю FCL на одном из таких языков, иначе ты даже классом string в этом языке пользоваться не сможешь.
Далее ты увидишь, что огромное количество сторонних библиотек написаны на более простых языках. А ты только что отрезал себя от этого множества, потому что как я показал, "коготок увяз — всей птичке пропасть".
По-моему, ты до сих пор не вьехал в то, что в рамках одной платформы языки с const и языки без const несовместимы. Вообще.
Либо const понижается в должности до хинта, который не влияет на поведение компилятора. Поскольку в слишком большом количестве случаев компилятор не сможет выполнить проверку константности, и ему придется отойти в сторонку. В таком виде этот "модификатор" прекрасно себя чувствует в рамках XML comments, где его найдет разработчик.
_FR>З.Ы. _FR>Кто такие S>>
OC8988: possible attempt to modify const object. Method Brahma.Meditiroval() misses the CompilerServices.ConstAttribute attribute
_FR>сообщения выдавать умеет?
Гипотетический компилятор, который поддерживает константность ссылок.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Sinclair wrote:
> _FR>И что плохого > В смысле "что плохого"? Ты только что получил compiler error > OC8988: possible attempt to modify const object. Method > Brahma.Meditiroval() misses the CompilerServices.ConstAttribute attribute > После этого ты вздыхаешь и убираешь const от параметра.
Нет. После этого смотрится нужна ли реально модификация, или можно
сделать локальную копию и использовать ее.
Если модификация действительно нужна, то можно использовать const_cast,
либо поставить mutable или убрать константность.
> После чего понимаешь, что const — штука хорошая, но нежизнеспособная.
Здравствуйте, Cyberax, Вы писали:
C>Нет. После этого смотрится нужна ли реально модификация, или можно C>сделать локальную копию и использовать ее.
Гм. Вводить локальную копию только ради того, чтобы обойти отсутствие атрибута? C>Если модификация действительно нужна, то можно использовать const_cast, C>либо поставить mutable или убрать константность.
Гм. const_cast полностью противоречит идеологии безопасного программирования. Так же, как и reinterpret_cast. Если контракт так легко нарушить, то может быть не стоит его подписывать? >> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. C>В С++ нормально работает.
Неа. У Страуструпа, помнится, было упомянуто что-то типа "либо используйте const во всей-всей программе, либо не используйте вообще". По большей части народ пишет вторым способом. И это при том, что стандартная библиотека все-таки аккуратно написана с использованием const (что неверно для FCL, как я уже говорил).
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Здравствуйте, Дарней, Вы писали:
Д>Например, такой вариант — "другой язык" не понимает, что такое константа, и радостно пытается модифицировать эту переменную. После чего ВМ выдает ему исключением по мордасам. Д>Разве плохо?
И эта воображаемая ВМ имеет та-акую замечательную производительность, что застрелиться можно.
Здравствуйте, anton_t, Вы писали:
_>И эта воображаемая ВМ имеет та-акую замечательную производительность, что застрелиться можно.
write barrier же живет, и ничего? хотя там потери должны намного побольше быть, если я правильно понимаю
к тому же, по хорошему, проверку корректности присваиваний можно выполнять всего один раз — при верификации кода
Здравствуйте, Sinclair, Вы писали:
>>> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. C>>В С++ нормально работает. S>Неа. У Страуструпа, помнится, было упомянуто что-то типа "либо используйте const во всей-всей программе, либо не используйте вообще". По большей части народ пишет вторым способом.
Не верю.
Без const на C++ программируют только те, кто еще про const не знают. Или не хотят научиться нормально на C++ программировать.
... << RSDN@Home 1.1.4 stable rev. 510>>
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, Дарней, Вы писали:
_>>И эта воображаемая ВМ имеет та-акую замечательную производительность, что застрелиться можно.
Д>write barrier же живет, и ничего? хотя там потери должны намного побольше быть, если я правильно понимаю Д>к тому же, по хорошему, проверку корректности присваиваний можно выполнять всего один раз — при верификации кода
Кстати, что ВМ не воображаемая, а вполне реальная — VW ST. Инженер писал, что реализация immutability флага добавилась "на дармовщинку". Как оно там внутри устроено я не знаю, но кроме как утилизации барьера других путей в голову не приходит. Кстати, не-мутируемость можно вкл/выкл на лету, что полезно для всякой ерунды связанной с БД.
Здравствуйте, Дарней, Вы писали:
ANS>>Кстати, что ВМ не воображаемая, а вполне реальная — VW ST.
Д>а не подскажешь, где почитать можно? а то по названию как-то не очень ищется
Реч идёт о VisualWorks Smalltalk. Но боюсь, что о флаге неизменности найти инфу там будет трудновато. Я нашел обзор.
Если кратко, то у любого объекта можно установить флаг неизменности (immutability flag). При попытке изменения объекта выбрасывается исключение. В нём, например, можно запомнить изменённый объект, разрешить мутацию и перезапустить операцию. Плюс, со средой идёт фрейворк, который позволяет задавать различные полиси реакции на такое исключение.
Здравствуйте, Sinclair, Вы писали:
S>Гм. const_cast полностью противоречит идеологии безопасного программирования. Так же, как и reinterpret_cast. Если контракт так легко нарушить, то может быть не стоит его подписывать?
Идеология тут не в том, чтобы сделать нарушение контракта максимально сложным хаком (потому что это противоречит целям гибкости языка), но в том, чтобы нарушение контракта было явным и не произошло случайно.
Согласись, довольно сложно случайно написать const_cast, не говоря уж о reinterpret_cast.
Суть в том, что компилятор — мужик, хорошо понимающий нужды программистов, и не желающий портить им жизнь. Он понимает, что раз уж программисту приходится кастить, то он это делает не от хорошей жизни, а из-за того, например, что та чудо-библиотека, которой он вынужден пользоваться, криво спроектирована, или еще по какой причине.
И он понимает, что, раз уж проргаммисту потребовалось кастить, то он найдет способ это сделать, так или иначе, и своего добьется, потому как царь зверей, так зачем заставлять его писать какие-то жуткие непереносимые хаки, если можно договориться полюбовно, а именно — просто попросив его высказать свои желания явно при помощи const_cast?
Так что явно контракт нарушить легко, неявно — невозможно.
Что и требуется, в общем-то.
>>> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. C>>В С++ нормально работает. S>Неа. У Страуструпа, помнится, было упомянуто что-то типа "либо используйте const во всей-всей программе, либо не используйте вообще". По большей части народ пишет вторым способом. И это при том, что стандартная библиотека все-таки аккуратно написана с использованием const (что неверно для FCL, как я уже говорил).
Ну, народ всякий бывает, это верно, некоторые вообще циклов не признают, все через goto :)
Что объезжать код таких чудо-деятелей, как раз и приходится кастить (у нас как раз такая кривая библиотека — после трех лет настойчивых просьб они наконец удосужились вставить в их класс хэша константную функцию поиска, а все эти три года да, приходилось кастить — ну а что делать, за все надо платить. Зато каждый каст явственно виден в программе и цель каждого каста предельно ясна — согласись, это гораздо лучше, чем не использовать констов вообще).
Здравствуйте, Cyberax, Вы писали:
C>Нет. После этого смотрится нужна ли реально модификация, или можно C>сделать локальную копию и использовать ее.
Локальная копия чего? Класса? То это часто практически невозможно. Если ссылки — то это уже не const.
>> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. C>В С++ нормально работает.
Не сравнивай. С++ — это один язык высокого уровня. В C++ можно по коду корректно проверить работает ли константность. В JIT компиляция происходит во время выполнения, не все сразу, и не пользуясь излишними ресурсами компьютера в виде памяти. Единственный выход — аттрибуты в информации о типах о которых знает компилятор языка. Но если попал на язык который не поддерживает константность, то ничего не поможет.
Здравствуйте, eao197, Вы писали: E>Не верю. E>Без const на C++ программируют только те, кто еще про const не знают. Или не хотят научиться нормально на C++ программировать.
Может быть.
1.1.4 stable rev. 510
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Sinclair wrote:
> C>Нет. После этого смотрится нужна ли реально модификация, или можно > C>сделать локальную копию и использовать ее. > Гм. Вводить локальную копию только ради того, чтобы обойти отсутствие > атрибута?
Так ведь ради чего-то этот атрибут ставился? Возможно, что другой код
написан с рассчетом, что объект не будет меняться.
void log_name(std::string &_name)
{
std::transform(_name.begin(),_name.end(),to_upper_case()); //А
теперь компилиться
cout<<_name;
}
...
std::string str=get_user_name();
log_name(str);
//А где-то здесь упадет....
Я знаю, что в C# строки иммутабельны (как раз по этой причине ), но
сам принцип, я надеюсь, понятен.
> C>Если модификация действительно нужна, то можно использовать const_cast, > C>либо поставить mutable или убрать константность. > Гм. const_cast полностью противоречит идеологии безопасного > программирования. Так же, как и reinterpret_cast. Если контракт так > легко нарушить, то может быть не стоит его подписывать?
Изредка бывает нужно. Точно так же как и касты Object->Concrete Class —
тоже ведь небезопасно, но иногда необходимо.
>>> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. > C>В С++ нормально работает. > Неа. У Страуструпа, помнится, было упомянуто что-то типа "либо > используйте const во всей-всей программе, либо не используйте вообще".
Ну примерно так и получается. Можно перефразировать практически для
всего: "Либо используйте generic'и по всей программе, либо не
используйте вообще", "Либо используйте исключения..." и т.п.
> По большей части народ пишет вторым способом.
Я пишу аккуратно, boost тоже очень хорош в этом отношении, как и
остальные используемые мной библиотеки.
GlebZ wrote:
> C>Нет. После этого смотрится нужна ли реально модификация, или можно > C>сделать локальную копию и использовать ее. > Локальная копия чего? Класса?
Значения переменной. В C# это называется "клонирование".
>>> После чего понимаешь, что const — штука хорошая, но нежизнеспособная. > C>В С++ нормально работает. > Не сравнивай. С++ — это один язык высокого уровня. В C++ можно по коду > корректно проверить работает ли константность.
Вообще-то константность в С++ записывается в mangled name. То есть я
могу использовать реализации классов в сторонней библиотеке без боязни
случайно нарушить контсантность.
> Единственный выход — аттрибуты в информации о типах о которых знает > компилятор языка. Но если попал на язык который не поддерживает > константность, то ничего не поможет.
Выход простой — такой язык будет видеть только неконстантные методы.
Здравствуйте, Cyberax, Вы писали:
C>Так ведь ради чего-то этот атрибут ставился? Возможно, что другой код C>написан с рассчетом, что объект не будет меняться.
Нет. Проблема как раз в том, что метод на самом деле не меняет объект. Просто у нас нет способа это проверить — он скомпилирован отсталым компилятором. C>Изредка бывает нужно. Точно так же как и касты Object->Concrete Class — C>тоже ведь небезопасно, но иногда необходимо.
Они безопасны потому, что в случае косяка мы получим не UB, а InvalidCastException. В дотнете нет сейф-аналога reinterpret_cast.
Если мы попробуем применить такой же подход в нашем случае, то просто отложим проблему в рантайм — среда все равно выкинет исключение при касте, т.к. объект действительно константный.
C>Я пишу аккуратно, boost тоже очень хорош в этом отношении, как и C>остальные используемые мной библиотеки.
Ок, ладно, поверим в то, что в мире плюсов все хорошо. Я вот бегло глянул в MFC от 2005 студии — все в порядке, конст используется. Отлично.
Но перенести все то же в .Net, особенно "не затрагивая внутренности", как заказывал автор темы
Здравствуйте, Cyberax, Вы писали:
C>Значения переменной. В C# это называется "клонирование".
Начнем сначала. В C# есть два вида объектов — reference type и value type. Value type так и так по умолчанию передают копию(то есть read only). То есть половина функциональности const просто не нужна. Reference type — передается по ссылке. Но так же как и в С++, если нет конструктора копирования, то пообъектно ты не скопируешь. Только там не конструктор копирования а IClonable. При этом нужно учитывать что он реализуется только там, где он действительно нужен.
C>Вообще-то константность в С++ записывается в mangled name. То есть я C>могу использовать реализации классов в сторонней библиотеке без боязни C>случайно нарушить контсантность.
Можешь.
C>Выход простой — такой язык будет видеть только неконстантные методы.
Что и требовалось доказать. Значит мы ввалились в то, что в данных условиях мы противоречим самому духу Net(а именно многоязычности) и эта функциональность больше мешает чем от нее пользы.
Sinclair,
> C>Изредка бывает нужно. Точно так же как и касты Object->Concrete Class — тоже ведь небезопасно, но иногда необходимо.
> Они безопасны потому, что в случае косяка мы получим не UB, а InvalidCastException. В дотнете нет сейф-аналога reinterpret_cast. Если мы попробуем применить такой же подход в нашем случае, то просто отложим проблему в рантайм — среда все равно выкинет исключение при касте, т.к. объект действительно константный.
const вовсе не обязательно означает константность объекта; в большинстве случаев как раз наоборот, он означает константность пути доступа к нему. Например, какой из объектов константен в следующем случае?
class C { };
void f(C const& c)
{
}
int main()
{
C c;
f(c);
}
Posted via RSDN NNTP Server 2.0 beta
Легче одурачить людей, чем убедить их в том, что они одурачены. — Марк Твен
Sinclair wrote:
> C>Так ведь ради чего-то этот атрибут ставился? Возможно, что другой код > C>написан с рассчетом, что объект не будет меняться. > Нет. Проблема как раз в том, что метод на самом деле *не меняет* > объект. Просто у нас нет способа это проверить — он скомпилирован > отсталым компилятором.
Тогда const_cast и надеяться, что он действительно объект не меняет.
> C>Изредка бывает нужно. Точно так же как и касты Object->Concrete Class — > C>тоже ведь небезопасно, но иногда необходимо. > Они безопасны потому, что в случае косяка мы получим не UB, а > InvalidCastException. В дотнете нет сейф-аналога reinterpret_cast. > Если мы попробуем применить такой же подход в нашем случае, то просто > отложим проблему в рантайм — среда все равно выкинет исключение при > касте, т.к. объект действительно константный.
Ну и вернемся к чему начинали — если не снимать const, то все нормально.
При использовании const_cast можем получить exception в runtime.
По-моему, вполне нормально.
> Но перенести все то же в .Net, особенно "не затрагивая внутренности", > как заказывал автор темы > <http://rsdn.ru/forum/Message.aspx?mid=1496478&only=1>
Не понимаю. Почему const нельзя сделать синтаксическим сахаром только одного языка? Скажем, W#
Ситуация W# зовет f(const TObject x) из W# — все нормально.
Ситуация С# зовет f(const TObject x) из W# — все нормально. Почему C# не должен видеть такие методы? Это ограничение на вызваемую сторону, а не на вызывающую.
Ситуация W# зовет f(TObject x) из C#, где TObject — всё плохо. Надо использовать const_cast и верить документации, что метод C# не будет менять объект. Если const_cast слишком много, то это повод что бы вообще отказатся в вызывающем коде от константности TObject(но только для него, а не для всего остального).
Правильно работающая программа — просто частный случай Undefined Behavior