AddRef/Release/QueryInterface - const?
От: Andrew S Россия http://alchemy-lab.com
Дата: 23.11.09 15:16
Оценка:
Всем привет.

Есть некая иерархия, элементы которой имеют интрузивное управление временем жизни (а-ля COM).
Сейчас это просто AddRef/Release. Ну, для полноты картины, есть еще и QueryInterface.

Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.
Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

Аргументы за и против?

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

Спасибо!
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re: AddRef/Release/QueryInterface - const?
От: Sergey Chadov Россия  
Дата: 23.11.09 15:21
Оценка:
Здравствуйте, Andrew S, Вы писали:


AS>Есть некая иерархия, элементы которой имеют интрузивное управление временем жизни (а-ля COM).

AS>Сейчас это просто AddRef/Release. Ну, для полноты картины, есть еще и QueryInterface.

AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.


Мне что-то кажется, что последний Release может очень капитально поменять состояние объекта.

AS>Например, в большинстве распространненных фреймворках такие методы неконстантны (точнее, я не знаю ни одного, где они или их аналоги константны).


Они в основном ориентироаны на С, а не на С++
--
Sergey Chadov

... << RSDN@Home 1.2.0 alpha rev. 685>>
Re: AddRef/Release/QueryInterface - const?
От: ononim  
Дата: 23.11.09 15:24
Оценка: :)
AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.
Рассуждение от противного — с точки зрения пользователя вызов метода происходит либо для изменения состояния объекта (const недопустим), либо для опроса состояния объекта (const допустим). В данном случае ничего не опрашиваем, а следовательно — ...
Как много веселых ребят, и все делают велосипед...
Re[2]: AddRef/Release/QueryInterface - const?
От: Sni4ok  
Дата: 23.11.09 15:28
Оценка: +1
Здравствуйте, Sergey Chadov, Вы писали:

SC>Мне что-то кажется, что последний Release может очень капитально поменять состояние объекта.


и что с того? константный указатель можно удалять, так что это вписывается в плюсовую концепцию
Re: AddRef/Release/QueryInterface - const?
От: Sni4ok  
Дата: 23.11.09 15:29
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.

AS>Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

имхо абсолютно побарабану.
Re: AddRef/Release/QueryInterface - const?
От: Тот кто сидит в пруду Россия  
Дата: 23.11.09 15:59
Оценка: 14 (1) +1
Здравствуйте, Andrew S, Вы писали:

AS>Есть некая иерархия, элементы которой имеют интрузивное управление временем жизни (а-ля COM).

AS>Сейчас это просто AddRef/Release. Ну, для полноты картины, есть еще и QueryInterface.

AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.

AS>Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

AS>Аргументы за и против?


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

AS>Например, в большинстве распространненных фреймворках такие методы неконстантны (точнее, я не знаю ни одного, где они или их аналоги константны).


А в этих фреймворках вообще константные методы в интерфейсах поддерживаются?
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: AddRef/Release/QueryInterface - const?
От: Кодт Россия  
Дата: 23.11.09 17:10
Оценка: 7 (1)
Здравствуйте, Andrew S, Вы писали:

AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.

AS>Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

Допустима, ценой небольших (? зависит от того, сколько уже напедалили) затрат на гигиену кода, во-первых, и потерей совместимости с настоящим COM, во-вторых.
Подсчёт ссылок — элементарно, у реализации нужно объявить mutable счётчик.
А QueryInterface придётся обернуть: вызов этой функции над константным/неконстантным умным указателем ведёт к вызову метода (константного) у указуемого объекта и наложению/снятию константности на результат.
... << RSDN@Home 1.2.0 alpha 4 rev. 1237>>
Перекуём баги на фичи!
Re[2]: AddRef/Release/QueryInterface - const?
От: Erop Россия  
Дата: 23.11.09 19:23
Оценка:
Здравствуйте, ononim, Вы писали:

O>Рассуждение от противного — с точки зрения пользователя вызов метода происходит либо для изменения состояния объекта (const недопустим), либо для опроса состояния объекта (const допустим). В данном случае ничего не опрашиваем, а следовательно — ...


Моё мнение
Автор: Erop
Дата: 04.09.07
, во всяком случае пока, другое...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[3]: AddRef/Release/QueryInterface - const?
От: ononim  
Дата: 23.11.09 20:00
Оценка: -1
O>>Рассуждение от противного — с точки зрения пользователя вызов метода происходит либо для изменения состояния объекта (const недопустим), либо для опроса состояния объекта (const допустим). В данном случае ничего не опрашиваем, а следовательно — ...

E>Моё мнение
Автор: Erop
Дата: 04.09.07
, во всяком случае пока, другое...

слишком много букав
истина — она в краткости
Как много веселых ребят, и все делают велосипед...
Re[3]: AddRef/Release/QueryInterface - const?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 24.11.09 05:20
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, ononim, Вы писали:


O>>Рассуждение от противного — с точки зрения пользователя вызов метода происходит либо для изменения состояния объекта (const недопустим), либо для опроса состояния объекта (const допустим). В данном случае ничего не опрашиваем, а следовательно — ...


E>Моё мнение
Автор: Erop
Дата: 04.09.07
, во всяком случае пока, другое...


Хорошее мнение . Хочу подкрепить фактами насчёт "нарваться при снятии истинной константности". Действительно нарывался при программировании под Palm с использованием CodeWarrior`а: снятие истинной константности с применением C-style каста ((int)val) приводило к системным ошибкам доступа. На тот момент времени разбираться не было, но по симптомам было похоже, что компилятор с целью оптимизации размещал константы в том сегменте, который не загружался в область памяти, доступную для изменения (она на Palm`ах была весьма дорогой). Правда применение C++ стиля для снятия константности (const_cast<int>(val)) решало проблему. Так что вы правы, но отчасти: const_cast для снятия истинной константности применять можно, а вот C-style cast — это аналог reinterpret_cast`а — его применять для этих целей нельзя ни в коем случае...
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[4]: AddRef/Release/QueryInterface - const?
От: Тот кто сидит в пруду Россия  
Дата: 24.11.09 07:50
Оценка:
Здравствуйте, Mr. None, Вы писали:

O>>>Рассуждение от противного — с точки зрения пользователя вызов метода происходит либо для изменения состояния объекта (const недопустим), либо для опроса состояния объекта (const допустим). В данном случае ничего не опрашиваем, а следовательно — ...


E>>Моё мнение
Автор: Erop
Дата: 04.09.07
, во всяком случае пока, другое...


MN>Хорошее мнение . Хочу подкрепить фактами насчёт "нарваться при снятии истинной константности". Действительно нарывался при программировании под Palm с использованием CodeWarrior`а: снятие истинной константности с применением C-style каста ((int)val) приводило к системным ошибкам доступа. На тот момент времени разбираться не было, но по симптомам было похоже, что компилятор с целью оптимизации размещал константы в том сегменте, который не загружался в область памяти, доступную для изменения (она на Palm`ах была весьма дорогой). Правда применение C++ стиля для снятия константности (const_cast<int>(val)) решало проблему.


Ссылка тут не пропущена случаем? Потому что без ссылки или указателя и говорить-то не о чем...

MN> Так что вы правы, но отчасти: const_cast для снятия истинной константности применять можно, а вот C-style cast — это аналог reinterpret_cast`а — его применять для этих целей нельзя ни в коем случае...


Ничего подобного, то, что у вас const_cast не приводил к ошибкам — всего лишь один из вариантов UB Стандарт гляньте, там довольно ясно написано, что снимать константность можно только с алиаса к значению, а не с самого значения.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[4]: AddRef/Release/QueryInterface - const?
От: Erop Россия  
Дата: 24.11.09 10:03
Оценка:
Здравствуйте, Mr. None, Вы писали:

MN>Правда применение C++ стиля для снятия константности (const_cast<int>(val)) решало проблему. Так что вы правы, но отчасти: const_cast для снятия истинной константности применять можно, а вот C-style cast — это аналог reinterpret_cast`а — его применять для этих целей нельзя ни в коем случае...


Ну это от платформы/реализации зависит. Снятие истинной константности, вернее попытка изменить истинную константу -- это неспецифицированное или неопределённое поведение (не помню точно какое из двух) Думаю, что неопределённое.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: AddRef/Release/QueryInterface - const?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 24.11.09 13:11
Оценка:
Здравствуйте, Тот кто сидит в пруду, Вы писали:

ТКС>Здравствуйте, Mr. None, Вы писали:


MN>> Так что вы правы, но отчасти: const_cast для снятия истинной константности применять можно, а вот C-style cast — это аналог reinterpret_cast`а — его применять для этих целей нельзя ни в коем случае...


ТКС>Ничего подобного, то, что у вас const_cast не приводил к ошибкам — всего лишь один из вариантов UB Стандарт гляньте, там довольно ясно написано, что снимать константность можно только с алиаса к значению, а не с самого значения.


const int val = 0;
...
(int)val = 2; // вот тут на некоторых видаж Palm имеем системное исключение - попытка записи в недопустимую область памяти



const int val = 0;
...
const_cast<int>(val) = 2; // всё нормально
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[5]: AddRef/Release/QueryInterface - const?
От: Mr. None Россия http://mrnone.blogspot.com
Дата: 24.11.09 13:12
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, Mr. None, Вы писали:


MN>>Правда применение C++ стиля для снятия константности (const_cast<int>(val)) решало проблему. Так что вы правы, но отчасти: const_cast для снятия истинной константности применять можно, а вот C-style cast — это аналог reinterpret_cast`а — его применять для этих целей нельзя ни в коем случае...


E>Ну это от платформы/реализации зависит. Снятие истинной константности, вернее попытка изменить истинную константу -- это неспецифицированное или неопределённое поведение (не помню точно какое из двух) Думаю, что неопределённое.


См. здесь
Автор: Mr. None
Дата: 24.11.09
Компьютер сделает всё, что вы ему скажете, но это может сильно отличаться от того, что вы имели в виду.
Re[6]: AddRef/Release/QueryInterface - const?
От: Тот кто сидит в пруду Россия  
Дата: 24.11.09 13:45
Оценка: +1
Здравствуйте, Mr. None, Вы писали:

MN>
MN>const int val = 0;
MN>...
MN>const_cast<int>(val) = 2; // всё нормально
MN>


В таком варианте VC даже не компилирует:

1>.\testInst.cpp(80) : error C2440: 'const_cast' : cannot convert from 'const int' to 'int'
1> Conversion is a valid standard conversion, which can be performed implicitly or by use of static_cast, C-style cast or function-style cast


Если добавить ссылку — написать
const_cast<int&>(val) = 2;

, то это будет всего лишь разновидность UB. Никто не гарантирует, что всё нормально будет на всех платформах. На пальме может и сработает, а где-нибудь да грохнется.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re: AddRef/Release/QueryInterface - const?
От: Alexander G Украина  
Дата: 24.11.09 13:56
Оценка: 7 (1)
Здравствуйте, Andrew S, Вы писали:

AS>Всем привет.


AS>Есть некая иерархия, элементы которой имеют интрузивное управление временем жизни (а-ля COM).

AS>Сейчас это просто AddRef/Release. Ну, для полноты картины, есть еще и QueryInterface.

AS>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.

AS>Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

AS>Аргументы за и против?


AS>Например, в большинстве распространненных фреймворках такие методы неконстантны (точнее, я не знаю ни одного, где они или их аналоги константны).


AS>Спасибо!


* Делал у себя с mutable счётчиком и const'ными addref-release для использования с boost::intrusive_ptr

boost::intrusive_ptr<const P> p1;
boost::intrusive_ptr<const P> p2 = p1;

во второй строке вызывается увеличение числа ссылок, оно должно быть константным, иначе не скомпилируется.

* Число ссылок не является состоянием объекта

* delete таки принимает const указатель, удаление объекта — это уже не изменение его состояния.
Русский военный корабль идёт ко дну!
Re: AddRef/Release/QueryInterface - const?
От: Andrew S Россия http://alchemy-lab.com
Дата: 24.11.09 19:33
Оценка:
Ок, аргументация понятна.

Спасибо всем за ответы
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[2]: AddRef/Release/QueryInterface - const?
От: Andrew S Россия http://alchemy-lab.com
Дата: 24.11.09 19:37
Оценка:
AS>>Поступило предложение сделать эти методы константными. Основной аргумент — с точки зрения пользователя эти методы не меняют состояние объекта.
AS>>Интересует мнение общественности — насколько допустима такая трактовка? Вообще, имеет ли право на жизнь const в абстрактных интерфейсах?

К>Допустима, ценой небольших (? зависит от того, сколько уже напедалили) затрат на гигиену кода, во-первых, и потерей совместимости с настоящим COM, во-вторых.


А что имеется в виду под потерей совместимости? Ведь все равное от кома и обратно нужны адаптеры, так что...

К>Подсчёт ссылок — элементарно, у реализации нужно объявить mutable счётчик.


Реализация понятна Интересуют аргументы за и против наличия вышеуказанных константных методов у интерфейсов. Взять тот же ice — там интрузивные операции неконстантны.

К>А QueryInterface придётся обернуть: вызов этой функции над константным/неконстантным умным указателем ведёт к вызову метода (константного) у указуемого объекта и наложению/снятию константности на результат.


В смысле, писАть const objptr<Interface> ? Или все-таки правильнее objptr<const Interface>, и ничего не оборачивать?
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Re[3]: AddRef/Release/QueryInterface - const?
От: Кодт Россия  
Дата: 24.11.09 20:35
Оценка:
Здравствуйте, Andrew S, Вы писали:

AS>А что имеется в виду под потерей совместимости? Ведь все равное от кома и обратно нужны адаптеры, так что...


Ну, например, Windows Platform SDK поставляется с .h-файлами объявлений интерфейсов. Будешь переделывать?
Также придётся допилить трансляцию .idl, потому что у IUnknown методы неконстантные.

На самом деле, проще подстроиться под ком. Всё равно, если пользуешься умными указателями, то сам напрямую функции IUnknown не вызываешь. Так вот, можно допилить умные указатели, чтобы они внутри снимали константность при вызове AddRef/Release/QueryInterface А все остальные методы — вызываются пользователем прямо у объекта, там константность как объявлена, такая и будет.

AS>Реализация понятна Интересуют аргументы за и против наличия вышеуказанных константных методов у интерфейсов. Взять тот же ice — там интрузивные операции неконстантны.


К>>А QueryInterface придётся обернуть: вызов этой функции над константным/неконстантным умным указателем ведёт к вызову метода (константного) у указуемого объекта и наложению/снятию константности на результат.


AS>В смысле, писАть const objptr<Interface> ? Или все-таки правильнее objptr<const Interface>, и ничего не оборачивать?


В смысле,
objptr<const X> cx;
objptr<const Y>(cx)
    // превращается в
    const Y* y = 0;
    cx->QueryInterfaceConst(__uuidof(Y), (void const**)&y);
    return objptr<const Y>(y);

objptr<X> mx;
objptr<Y>(mx)
    // соответственно,
    const Y* y = 0;
    mx->QueryInterfaceConst(__uuidof(Y), (void const**)&y);
    return objptr<Y>(const_cast<Y*>(y)); // вот он, легальный конст-каст

// аналогично, только в обратную сторону, будет внутреннее устройство
// если функция QueryInterface неконстантная

// смешанные случаи
objptr<const Y>(mx); // константность накладывается, всё законно
objptr<Y>(cx); // константность теряется - должны сделать ошибку компиляции


Ну а писать const objptr<X> против objptr<const X> — это то же самое, как X* const против X const*.
Делать глубокую константность — т.е. const objptr<X> ~ X const* const — в общем случае не стоит, т.к. ломается традиционная семантика.
Хотя иногда глубокая константность может пригодиться — например, для объявления агрегатов и подчинённых объектов.
Тогда лучше завести отдельный класс указателя.
Перекуём баги на фичи!
Re[4]: AddRef/Release/QueryInterface - const?
От: Andrew S Россия http://alchemy-lab.com
Дата: 24.11.09 20:41
Оценка:
AS>>А что имеется в виду под потерей совместимости? Ведь все равное от кома и обратно нужны адаптеры, так что...

К>Ну, например, Windows Platform SDK поставляется с .h-файлами объявлений интерфейсов. Будешь переделывать?

К>Также придётся допилить трансляцию .idl, потому что у IUnknown методы неконстантные.

Не-не, IUnknown у нас нет. У нас собственная компонентная модель

К>На самом деле, проще подстроиться под ком. Всё равно, если пользуешься умными указателями, то сам напрямую функции IUnknown не вызываешь. Так вот, можно допилить умные указатели, чтобы они внутри снимали константность при вызове AddRef/Release/QueryInterface А все остальные методы — вызываются пользователем прямо у объекта, там константность как объявлена, такая и будет.


AS>>Реализация понятна Интересуют аргументы за и против наличия вышеуказанных константных методов у интерфейсов. Взять тот же ice — там интрузивные операции неконстантны.


К>>>А QueryInterface придётся обернуть: вызов этой функции над константным/неконстантным умным указателем ведёт к вызову метода (константного) у указуемого объекта и наложению/снятию константности на результат.


AS>>В смысле, писАть const objptr<Interface> ? Или все-таки правильнее objptr<const Interface>, и ничего не оборачивать?


К>Ну а писать const objptr<X> против objptr<const X> — это то же самое, как X* const против X const*.

К>Делать глубокую константность — т.е. const objptr<X> ~ X const* const — в общем случае не стоит, т.к. ломается традиционная семантика.

Все, понял, что имеется в виду. Тут все просто — 2 версии QueryInterface, для const и не const.

Это, кстати, один из минусов наличия const.
http://www.rusyaz.ru/pr — стараемся писАть по-русски
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.