Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Offsetof - struct 
:(
    Опции темы
500mhz
Дата 14.3.2012, 01:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



Помогите ) туплю сижу,собственно пример и output
http://codepad.org/3tR7DXiC

В теории прибавляемое смещение 0х8, на практике получаем 0х20

сорри если вопрос глупый, сонный я )


--------------------

PM MAIL ICQ   Вверх
volatile
Дата 14.3.2012, 04:40 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(500mhz @  14.3.2012,  01:32 Найти цитируемый пост)
В теории прибавляемое смещение 0х8, на практике получаем 0х20

500mhz, это же арифметика указателей.
указатель + N ==> передвинуть указатель на N элементов. (не на N байт!!!)
т.е.
указатель + N ==> это значение указателя + N*(размер того, на что он указывает).

в вашем случае
pVar + 8; 
означает: передвинуть указатель на 8 элементов.
а так, как pVar это указатель на int, sizeof (int) = 4, то к адресу указателя прибаляется
8*4=32 (0x20)
Если бы pVar указывал на char, было бы 8

Добавлено @ 04:41
можно здесь почитать, например:
http://www.cs.umd.edu/class/sum2003/cmsc31...Op/pointer.html


Это сообщение отредактировал(а) volatile - 14.3.2012, 04:47
PM MAIL   Вверх
500mhz
Дата 14.3.2012, 15:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



это все понятно

вообщем мне нада сделать следующее
есть адрес неких данных
есть оффсеты
нужно прибавит к адресу оффсет и из получившегося адреса взять значение

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

Код

mov esi,addr
mov esi,[esi+offset]


как это красиво сделать на С ?


--------------------

PM MAIL ICQ   Вверх
feodorv
Дата 14.3.2012, 19:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(500mhz @  14.3.2012,  16:18 Найти цитируемый пост)
как это красиво сделать на С ? 

Красиво не получится:
Код

* (int *) (&((unsigned char *) ptr)[offset])


Или так:
Код

#define OFFSET_VALUE(addr,offset,type) \
    (* (type *) (&((unsigned char *) (addr))[offset]))

Пусть не так красиво, как в асме, но зато можно short, long long и т.п. юзать)))

Это сообщение отредактировал(а) feodorv - 14.3.2012, 20:25


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
500mhz
Дата 14.3.2012, 21:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



взрыв мозга )))
feodorv +1

пс
и эти люди говорят что асм трудно читаем и понимаем? )))


--------------------

PM MAIL ICQ   Вверх
sergioK1
Дата 14.3.2012, 22:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 417
Регистрация: 30.1.2011

Репутация: нет
Всего: нет



похожая ситуация , добаваил один чар 
Код

  struct asshole
 {
 unsigned long shit1;
 unsigned long shit2;
 char ch;
 unsigned char shit3;

  .... 

 printf ("size  =%d \n",sizeof(struct asshole));
 };


  должен быть 13 , а он 16 ,  откуда и зачем ?


P.S помню что где-то осуждалось, 



Это сообщение отредактировал(а) sergioK1 - 14.3.2012, 23:00
PM MAIL   Вверх
feodorv
Дата 14.3.2012, 23:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(sergioK1 @  14.3.2012,  23:56 Найти цитируемый пост)
должен быть 13 , а он 16

Всё правильно, выравнивание по 4-х байтной границе.


Цитата(sergioK1 @  14.3.2012,  23:56 Найти цитируемый пост)
P.S помню что где-то осуждалось, 

Здесь точно обсуждалось ;)

Это сообщение отредактировал(а) feodorv - 14.3.2012, 23:46


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
500mhz
Дата 14.3.2012, 23:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



сделал так
Код

int *temp;
temp = (addr + offsetof(struct asshole,shit1));
addr = addr + *temp;


TCC компилит
а вот Pelles  говорит error и все тут (addr = addr + *temp)

интересно что говорит стандарт?


--------------------

PM MAIL ICQ   Вверх
volatile
Дата 15.3.2012, 01:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(500mhz @  14.3.2012,  23:59 Найти цитируемый пост)
а вот Pelles  говорит error и все тут (addr = addr + *temp)

А что такое addr? Если только это не void*, то строчка нормальная. Ошибок именно в ней быть не должно.

Цитата(500mhz @  14.3.2012,  23:59 Найти цитируемый пост)
temp = (addr + offsetof(struct asshole,shit1));

А вот здесь что-то не то.
500mhz, покажите что такое addr, не хочется строить догадки.

(Ну или почему не воспользоваться макросом от feodorv, вполне нормальное решение для С, имхо)
PM MAIL   Вверх
500mhz
Дата 15.3.2012, 20:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



volatile
Цитата

(Ну или почему не воспользоваться макросом от feodorv, вполне нормальное решение для С, имхо) 

интересно самому как бы сделать)

по коду
имеем int addr;

Цитата

temp = (addr + offsetof(struct asshole,shit1));

А вот здесь что-то не то.

во тут как раз самое то ) при компиляции  получаем addr + 0  (если shit1 первый мембер)


--------------------

PM MAIL ICQ   Вверх
feodorv
Дата 15.3.2012, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(500mhz @  15.3.2012,  21:53 Найти цитируемый пост)
интересно самому как бы сделать)

 smile 

Цитата(500mhz @  15.3.2012,  21:53 Найти цитируемый пост)
имеем int addr;

Почему addr именно int? smile 


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
500mhz
Дата 15.3.2012, 21:36 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



Цитата

Почему addr именно int?

а почему нет?


--------------------

PM MAIL ICQ   Вверх
feodorv
Дата 15.3.2012, 22:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2214
Регистрация: 30.7.2011

Репутация: 11
Всего: 45



Цитата(500mhz @  15.3.2012,  22:36 Найти цитируемый пост)
а почему нет? 

Ну это всё-таки адрес или нет?
Если адрес, то такое значение в Си может принимать только указатель:
Код

unsigned char *addr;


Поэтому-то такой код и даёт ошибку:
Цитата(500mhz @  15.3.2012,  00:59 Найти цитируемый пост)
int *temp;
temp = (addr + offsetof(struct asshole,shit1));

Напрямую присвоить указателю интегер значение в С запрещено (и правильно ;)
Если очень хочется (а это мало когда нужно) из интегера сделать адрес, то это можно сделать так:
Код

unsigned char *addr = (unsigned char *) 0x123456u;

то есть напрямую задав преобразование типов. 


И наоборот:
Код

int *temp;
unsigned int addr = (unsigned int) temp;

Однако в 64-битном окружении (а интегер там остаётся 32-битным) такое преобразование будет некорректным.


В любом случае, не стоит увлекаться такими преобразованиями. Пусть указатель остаётся указателем (то есть по значению - адресом), а интегер - интегером)))

Это сообщение отредактировал(а) feodorv - 15.3.2012, 22:56


--------------------
Напильник, велосипед, грабли и костыли - основные инструменты программиста...
PM MAIL   Вверх
500mhz
Дата 15.3.2012, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


шайтан
***


Профиль
Группа: Завсегдатай
Сообщений: 1017
Регистрация: 5.5.2008
Где: Киев / Italy

Репутация: нет
Всего: 14



feodorv
в моем случае addr это адрес начала заголовка данных в памяти
имеется struct который описывает заголовок, сам заголовок состоит из различных значений и смещений 
в результате берем адрес начала данных 0xf0000000 
прибавляем смещение  0xf0000000 + 0xa0
из полученого адреса 0xf000000a0 берем число которое интерпретируется
а) как значение
б) или как новое смещение


пс
просто меня ломает переписывать с 32 на 64 все это на асме ))) 



--------------------

PM MAIL ICQ   Вверх
volatile
Дата 16.3.2012, 00:13 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2107
Регистрация: 7.1.2011

Репутация: 37
Всего: 85



Цитата(500mhz @  15.3.2012,  23:25 Найти цитируемый пост)
ломает переписывать с 32 на 64 все это 
Ну если нужно 64, то инты точно не подойдут.

Можно как-то приблизительно, так:

Код

long *temp;
char *addr = (char*)начальное_смещение;
temp = (long*)(addr + offsetof(struct asshole,shit1));
addr += *temp;


PM MAIL   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0604 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.