как избежать проблем с выравниванием?
От: Аноним  
Дата: 16.10.09 14:30
Оценка:
Что гарантирует отсутствие проблем с выравниванием, побайтный доступ к памяти?:

void load(char const* buf)
{
unsigned long value = 0;
memcpy(&value, buf, sizeof(value));
}



А так?

void load(std::deque<char> const& buf)
{
unsigned long value = 0;
std::copy(buf.begin(), buf.begin() + sizeof(value),
    reinterpret_cast<char*>(&value));
}


Этого достаточно?
Re: как избежать проблем с выравниванием?
От: gear nuke  
Дата: 16.10.09 15:07
Оценка:
Здравствуйте, <Аноним>, Вы писали:

А>Что гарантирует отсутствие проблем с выравниванием


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

А>побайтный доступ к памяти?:


А>
А>void load(char const* buf)
А>{
А>unsigned long value = 0;
А>memcpy(&value, buf, sizeof(value));
А>}
А>


А>А так?


А>
А>void load(std::deque<char> const& buf)
А>{
А>unsigned long value = 0;
А>std::copy(buf.begin(), buf.begin() + sizeof(value),
А>    reinterpret_cast<char*>(&value));
А>}
А>


Оба варианта обращаются только к натурально-выравненным данным

А>Этого достаточно?


Смотря для чего. Вопрос не связан с low/big endian?
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[2]: как избежать проблем с выравниванием?
От: bad_coder  
Дата: 16.10.09 15:21
Оценка:
Здравствуйте, gear nuke, Вы писали:

GN>Здравствуйте, <Аноним>, Вы писали:


А>>Что гарантирует отсутствие проблем с выравниванием


GN>Стандарт. Все возможные данные уже выровнены, что бы получить невыровненные нужно прилагать усилия.

GN>Оба варианта обращаются только к натурально-выравненным данным

Ну вот те раз, а так!


void load(char const* buf)
{
unsigned short val1 = *reinterpret_cast<unsigned short const*>(buf);
buf += sizeof(unsigned short);
unsigned long val2 = *reinterpret_cast<unsigned long const*>(buf);
}


int main()
{
char* buf = new char[1000];
//.........
load(buf);
return 0;
}
Re[3]: как избежать проблем с выравниванием?
От: gear nuke  
Дата: 16.10.09 16:12
Оценка: -1
Здравствуйте, bad_coder, Вы писали:

_>Ну вот те раз, а так!


Так предприняты усилия, и присвоение val2 некорректно. С val1 проблем нет.

7.20.3 Memory management functions
1. The pointer returned if the allocation
succeeds is suitably aligned so that it may be assigned to a pointer to any type of object
and then used to access such an object or an array of such objects in the space allocated
(until the space is explicitly deallocated).

Это С, в С++ аналогично.

_>

_>void load(char const* buf)
_>{
_>unsigned short val1 = *reinterpret_cast<unsigned short const*>(buf);
_>buf += sizeof(unsigned short);
_>unsigned long val2 = *reinterpret_cast<unsigned long const*>(buf);
_>}


_>int main()
_>{
_>char* buf = new char[1000];
_>//.........
_>load(buf);
_>return 0;
_>}

_>
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: как избежать проблем с выравниванием?
От: andrey.desman  
Дата: 16.10.09 17:11
Оценка: +1
Здравствуйте, gear nuke, Вы писали:

GN>Так предприняты усилия, и присвоение val2 некорректно. С val1 проблем нет.


Чутье подсказывает, что с val1 так же все не очень гладко, хотя ссыками на стандарт по этому поводу бросаться не буду

Да вариантов масса может быть. Те же utf8 строки, десериализация, ...
Конкретно в load() указатель может прийти и не выровненый. Я не про operator new, а вообще. Когда-нибудь найдется кто-нибудь, кто именно так и сделает. На интеле оно отработает, а вот на том же арме рухнет. Так что проще это предусмотреть в самой функции.

А ответ: да. Побайтовый доступ решает проблему.
Re[2]: как избежать проблем с выравниванием?
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 17.10.09 19:22
Оценка: +2
Здравствуйте, gear nuke, Вы писали:

GN>Стандарт. Все возможные данные уже выровнены, что бы получить невыровненные нужно прилагать усилия.


buf может быть невыровнен.

Такой код
value = *reinterpret_cast<unsigned long *>(buf);

вместо мемсета может вызвать исключение (на процессорах, отличных от x86);
Re[3]: как избежать проблем с выравниванием?
От: gear nuke  
Дата: 17.10.09 22:14
Оценка:
Здравствуйте, R.O. Prokopiev, Вы писали:

ROP>buf может быть невыровнен.


Я разве утверждал, что нет Может, если постарасться.
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[4]: как избежать проблем с выравниванием?
От: gear nuke  
Дата: 17.10.09 22:37
Оценка:
Уточню

char* buf; // всегда выровнен.

long* p = new long; // выровнен 

p = reinterpret_cast<unsigned long *>(buf); // не всегда выровнен
.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re: как избежать проблем с выравниванием?
От: Тролль-323  
Дата: 18.10.09 13:03
Оценка: -2 :)
Дек из байтов — это мощно.

Не делайте так, это порнография.

А по вопросу — непонятно, что имеется в виду, какое выравнивание?
Re[2]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: Erop Россия  
Дата: 19.10.09 03:44
Оценка:
Здравствуйте, Тролль-323, Вы писали:

Т3>Дек из байтов — это мощно.

А в чём проблема-то?

Т3>Не делайте так, это порнография.

IMHO, порнография -- это совсем другое...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: как избежать проблем с выравниванием?
От: R.O. Prokopiev Россия http://127.0.0.1/
Дата: 19.10.09 08:15
Оценка:
Здравствуйте, gear nuke, Вы писали:
GN>Здравствуйте, R.O. Prokopiev, Вы писали:

ROP>>buf может быть невыровнен.

GN>Я разве утверждал, что нет
тут:
GN>>>Все возможные данные уже выровнены, что бы получить невыровненные нужно прилагать усилия.
Re[5]: как избежать проблем с выравниванием?
От: gear nuke  
Дата: 19.10.09 11:19
Оценка: +1
Здравствуйте, R.O. Prokopiev, Вы писали:

ROP>>>buf может быть невыровнен.

GN>>Я разве утверждал, что нет
ROP>тут:
GN>>>>Все возможные данные уже выровнены, что бы получить невыровненные нужно прилагать усилия.

reinterpret_cast это и есть "прилагать усилия". buf, имея тип char*, всегда будет указывать на выровненные данные (char)

Кроме того, результат такого каста неопределён:

5.2.10/7 A pointer to an object can be explicitly converted to a pointer to an object of different type. Except that converting an rvalue of type “pointer to T1” to the type “pointer to T2” (where T1 and T2 are object types and where the alignment requirements of T2 are no stricter than those of T1) and back to its original type yields the original pointer value, the result of such a pointer conversion is unspecified.

.
People who are more than casually interested in computers should have at least some idea of what the underlying hardware is like. Otherwise the programs they write will be pretty weird (c) D.Knuth
Re[3]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: Тролль-323  
Дата: 23.10.09 17:46
Оценка:
Т3>>Дек из байтов — это мощно.
E>А в чём проблема-то?

Ну, если вы знаете, как дек реализовывается, то для вас это будет очевидно. Например, в Microsoft (Dinkumware) STL дек выделяет элементы блоками максимум по восемь элементов — то есть, в данном случае, восемь байт. Накладные расходы на поддержание структуры данных и динамическое выделение памяти будут просто смехотворными по отношению к полезному количеству информации.
Re[4]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: Erop Россия  
Дата: 23.10.09 19:30
Оценка:
Здравствуйте, Тролль-323, Вы писали:

Т3>Ну, если вы знаете, как дек реализовывается, то для вас это будет очевидно. Например, в Microsoft (Dinkumware) STL дек выделяет элементы блоками максимум по восемь элементов — то есть, в данном случае, восемь байт. Накладные расходы на поддержание структуры данных и динамическое выделение памяти будут просто смехотворными по отношению к полезному количеству информации.


Странное решение. Неужели нет специализации?
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[5]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: Тролль-323  
Дата: 24.10.09 08:57
Оценка:
E>Странное решение. Неужели нет специализации?

Кстати, я наврал, не по восемь, а по 16, но это не суть. Просто дек для другого предназначен. Для байт, в крайнем случае, вектор.
Re[6]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: Erop Россия  
Дата: 24.10.09 20:29
Оценка:
Здравствуйте, Тролль-323, Вы писали:

Т3>Кстати, я наврал, не по восемь, а по 16, но это не суть. Просто дек для другого предназначен. Для байт, в крайнем случае, вектор.


Это всё, конечно, хорошо, но бывают всякие такие шаблонные машинки, в которых заранее не известно, что за тип будет их параметризовывать...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: как избежать проблем с выравниванием?
От: rg45 СССР  
Дата: 25.10.09 09:31
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Что гарантирует отсутствие проблем с выравниванием, побайтный доступ к памяти?:


А>
А>void load(char const* buf)
А>{
А>unsigned long value = 0;
А>memcpy(&value, buf, sizeof(value));
А>}
А>



При использовании подобного хака, ИМХО, вероятность получить проблемы с выравниванием скорее увеличивается.

Для того, чтобы избежать проблем с выравниванием полей в структурах и элементов в массивах, при ЛЮБОМ параметре выравнивания, ДОСТАТОЧНО того, чтобы размер всех используемых типов данных выражался бы степенью двойки (либо был кратен максимально возможной величине параметра выравнивания), и смещение каждого поля в структуре было бы кратно размеру этого поля (либо было кратно максимально возможной величине параметра выравнивания).
--
Re[2]: как избежать проблем с выравниванием?
От: bad_coder  
Дата: 26.10.09 14:24
Оценка:
Здравствуйте, rg45, Вы писали:


R>При использовании подобного хака, ИМХО, вероятность получить проблемы с выравниванием скорее увеличивается.


R>Для того, чтобы избежать проблем с выравниванием полей в структурах и элементов в массивах, при ЛЮБОМ параметре выравнивания, ДОСТАТОЧНО того, чтобы размер всех используемых типов данных выражался бы степенью двойки (либо был кратен максимально возможной величине параметра выравнивания), и смещение каждого поля в структуре было бы кратно размеру этого поля (либо было кратно максимально возможной величине параметра выравнивания).



Интересно услышать от автора пояснения, как в данном случае можно получить проблемы с выравниванием, а не голословное утверждение. А как вы предлагаете, считать 2 байтное целое число из буффера, который был заполнен данными, полученными по сети, к примеру?
Re[4]: Эх, кто ещё тут настоящей порнографии не видел? ;)
От: bad_coder  
Дата: 26.10.09 14:26
Оценка:
Здравствуйте, Тролль-323, Вы писали:


Т3>Ну, если вы знаете, как дек реализовывается, то для вас это будет очевидно. Например, в Microsoft (Dinkumware) STL дек выделяет элементы блоками максимум по восемь элементов — то есть, в данном случае, восемь байт. Накладные расходы на поддержание структуры данных и динамическое выделение памяти будут просто смехотворными по отношению к полезному количеству информации.


Возможно все равно работа с деком из байт будет быстрее из-за необходимости вставки в начало последовательности, все зависит от задачи, я бы не был так категоричен.
Re[3]: как избежать проблем с выравниванием?
От: rg45 СССР  
Дата: 26.10.09 20:45
Оценка:
Здравствуйте, bad_coder, Вы писали:

_>А как вы предлагаете, считать 2 байтное целое число из буффера, который был заполнен данными, полученными по сети, к примеру?


Протокол обмена данными по сети, безусловно, требует согласования, думаю, это очевидно. Если данные, полученные из буфера по сети, были сформированы, например, путем сериализации объекта определенной структуры, то можно адрес этого буфера просто интерпретировать как указатель на соответствующую структуру, и затем обратиться к соответсвующему полю при помощи естественной языковой конструкции. А если эта структура была построена по правилам, изложенным мной, то можно не бояться, что смещения отдельных полей "поползут" вследствие разных настроек выравнивания на клиентской и серверной сторонах.
--
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.