Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

Портабельный аналог offsetof для указателя на член класса

505
25 декабря 2009 года
vAC
343 / / 28.02.2006
Возникла проблема при написании кода для Play Station Portable. Нужно, имея указатель на член класса
 
Код:
VarType TClassType::* pvar;
вычислить его смещение относительно this. Компилятор PSP для первого члена возвращает в pvar значение 1, а не реальный 0. По аналогии с offsetof сделать не получилось, все равно смещение 1 для первого члена, хотя реально оно равно 0. Хотелось бы найти красивое решение, без условной компиляции. Кто нибудь его знает?
260
25 декабря 2009 года
Ramon
1.1K / / 16.08.2003
Конкретнее сформулируйте проблему, что есть, что надо получить и ваши предположительные решения данной проблемы. И побольше кода.
505
25 декабря 2009 года
vAC
343 / / 28.02.2006
Цитата: Ramon
Конкретнее сформулируйте проблему, что есть, что надо получить и ваши предположительные решения данной проблемы. И побольше кода.



Нужно получить смещение члена по pointer-to-member по аналогии с offsetof. Offsetof юзается так:

 
Код:
offset = offsetof(Vector2, x);


Но мне нужно получить тот же результат, но используя pointer-to-member:
 
Код:
float Vector2::* pm = &Vector2::x;
offset = ?;

реинтерпретирование pm как числа оказалось непортабельным, также как и использование нулевого указателя по аналогии с offsetof.
260
25 декабря 2009 года
Ramon
1.1K / / 16.08.2003
Это все частности, что вам надо, глобальнее?
505
25 декабря 2009 года
vAC
343 / / 28.02.2006
Цитата: Ramon
Это все частности, что вам надо, глобальнее?


именно это и надо, иначе придется переделывать много кода

260
25 декабря 2009 года
Ramon
1.1K / / 16.08.2003
Представьте контекст в котором будет юзаться оффсет как он выглядит сейчас и изменения которые вы внесли, иначе совершенно непонятно как и где соплями мазать.

PS: Надо видеть ситуацию целостно иначе вопрос останется без ответа.
505
25 декабря 2009 года
vAC
343 / / 28.02.2006
Цитата: Ramon
Представьте контекст в котором будет юзаться оффсет как он выглядит сейчас и изменения которые вы внесли, иначе совершенно непонятно как и где соплями мазать.

PS: Надо видеть ситуацию целостно иначе вопрос останется без ответа.



Для своей ситуации я нашел другое решение. Но эта задача (определение смещения по pointer-to-member) для меня все еще представляет академический интерес.

260
25 декабря 2009 года
Ramon
1.1K / / 16.08.2003
Цитата: vAC
Для своей ситуации я нашел другое решение.



Что и требовалось доказать.

PS: Академический и практический интерес представляют конкретные задачи, а не сферические кони в вакууме.

87
25 декабря 2009 года
Kogrom
2.7K / / 02.02.2008
Сферических коней уважаю, но понять не могу. Потому напишу быдлокод для уточнения:

Код:
struct Vector2
{
    double x;
    double y;
    Vector2():x(0), y(0){}
};

using namespace std;

int main()
{
    Vector2 *pv = 0;

    cout << (int)&pv->x - (int)pv << ' ';
    cout << (int)&pv->y - (int)pv << ' ';


    double Vector2::* px = &Vector2::x;
    double Vector2::* py = &Vector2::y;

    cout << (int)&(pv->*px) - (int)pv << ' ';
    cout << (int)&(pv->*py) - (int)pv << ' ';

    return 0;
}

У меня выводит 0 8 0 8.

Что надо поменять, чтобы вышло то, что хочет автор темы?
288
26 декабря 2009 года
nikitozz
1.2K / / 09.03.2007
Цитата: vAC
Компилятор PSP для первого члена возвращает в pvar значение 1, а не реальный 0.



А с чего вы взяли, что 0 - это реальное значение. То, что этот член описан у вас в классе первым, еще совсем не гарантирует, что его адрес будет равняться this.

505
28 декабря 2009 года
vAC
343 / / 28.02.2006
Всетаки код, построенный по аналогии с offsetof оказался рабочим)
извиняюсь, что ввел в заблуждение, видимо что-то проглючило.
Собственно есть например класс/структура
 
Код:
struct Vector {
  float x, y;
};


нужно вычислить например смещение к y. С помощью offsetof делается так:
 
Код:
[SIZE=2][COLOR=#010001][SIZE=2][COLOR=#010001]offset = offsetof[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]([/SIZE][SIZE=2][COLOR=#010001][SIZE=2][COLOR=#010001]Vector[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2], y[/SIZE][SIZE=2]);
[/SIZE]


А если имеем указатель на член, то так:
 
Код:
float Vector::*pm = &Vector::y;
offset = (size_t) [SIZE=2]&(([/SIZE][SIZE=2][COLOR=#010001][SIZE=2][COLOR=#010001]Vector[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2] *)(0)->*[/SIZE][SIZE=2][COLOR=#010001][SIZE=2][COLOR=#010001]pm[/COLOR][/SIZE][/COLOR][/SIZE][SIZE=2]);
[/SIZE][SIZE=2]
[/SIZE]
[SIZE=2][/SIZE]
[SIZE=2]проблема была в том, что имеющийся код реинтерпретировал pm как само смещение. Для всех компиляторов это было верно, кроме PSP, он давал значение на 1 большее.
[/SIZE]
87
28 декабря 2009 года
Kogrom
2.7K / / 02.02.2008
Решил таки посмотреть stddef.h из gcc:

Код:
/* Offset of member MEMBER in a struct of type TYPE. */
#ifndef __cplusplus
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#else
/* The cast to "char &" below avoids problems with user-defined
   "operator &", which can appear in a POD type.  */
#define offsetof(TYPE, MEMBER)                  \
  (__offsetof__ (reinterpret_cast <size_t>          \
                 (&reinterpret_cast <const volatile char &> \
                  (static_cast<TYPE *> (0)->MEMBER))))
#endif /* C++ */


Короче, опять я занимался изобретением велосипеда... Радует, что мой получился почти как стандартный.
260
28 декабря 2009 года
Ramon
1.1K / / 16.08.2003
Цитата: Kogrom
Решил таки посмотреть stddef.h из gcc:

Код:
/* Offset of member MEMBER in a struct of type TYPE. */
#ifndef __cplusplus
#define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
#else
/* The cast to "char &" below avoids problems with user-defined
   "operator &", which can appear in a POD type.  */
#define offsetof(TYPE, MEMBER)                  \
  (__offsetof__ (reinterpret_cast <size_t>          \
                 (&reinterpret_cast <const volatile char &> \
                  (static_cast<TYPE *> (0)->MEMBER))))
#endif /* C++ */


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


*Поднял палец*

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог