Здравствуйте, Bell, Вы писали:
B>Здравствуйте, remark, Вы писали:
B>Дело в 4.10/2, а пример вот он:
Честно говоря, я немного затрудняюсь с ходу трактовать 4.10/2
4.10/2
An rvalue of type “pointer to cv T ,” where T is an effective object type, can be converted to an rvalue of
type “pointer to cv void”. The result of converting a “pointer to cv T” to a “pointer to cv void” points
to the start of the storage location where the object of type T resides, as if the object is a most derived
object (1.8) of type T (that is, not a base class subobject). The null pointer value is converted to the null
pointer value of the destination type.
Разве указатель на объект как на MDT и как на подобъект другого объекта может различаться в принципе?
Я это смещение объяснил для себя несколько по-другому: как артефакт реализации виртуальных функций получаем, что в некоторой функции статический тип this есть T*, а реальное значение this получается указатель на какой-то другой объект Y*. Соотв. компилятору в реализации приходится это учитывать и смещать this при каждом использовании.
Следствие №1: это не регламентируется стандартом, т.к. реализация виртуальных функций не регламентируется.
Следствие №2: это проявляется не только при конвертации к void*, а при *любом* использовании. Например при конвертации к uintptr_t.
Следствие №3: вполне можно представить реализацию виртуальных функций, где статический и динамический типы this всегда будут совпадать, соотв. там не будет таких артефактов в принципе. Для этого, например, можно в таблице виртуальных функций вместе с каждым указателем хранить смещение от базового типа (где впервые объявлена виртуальная функция) до реального типа (в котором переопределена виртуальная функция). Тогда в месте вызова указатель будет соотв. смещаться. Хотя практически это наверное менее эффективно, чем делать это смещение уже внутри реальной функции.