засомневался, правильно ли я делаю.
По сети я получаю пакет само собой в виде нетипизированного char-буфера. Формат пакета таков: в первых 4 байтах идет размер (unit32), потом уже сам пакет.
В данный момент я делаю так:
bool parseReceivedBuffer(const char* buf, size_t size)
{
if (size < sizeof(boost::uint32_t))
return false;
boost::uint32_t packetSize = *(boost::uint32_t*)(buf);
buf += packetSize;
// дальше парсю сам пакет..
}
Насколько корректна выделенная строка?
А если сделать так
засомневался, правильно ли я делаю. ПВ>По сети я получаю пакет само собой в виде нетипизированного char-буфера. Формат пакета таков: в первых 4 байтах идет размер (unit32), потом уже сам пакет.
Так скажем, с практической точки зрения тут всё будет работать, и при агрессивной оптимизации компилятора проблем из-за aliasing не возникнет, т.к. буфер у тебя константный и ты в него ничего не пишешь. Проблемы с aliasing возникают при модификациях буфера, т.к. возникают проблемы с выстраиванием зависимостей по данным.
Правда смотри осторожно, если вне этой функции ты модифицируешь буфер, т.к. эта функция может быть встроена. Получай доступ к одним и тем же данным только через один и то же тип.
С теоретической точки зрения... абстрагируемся от факта, что любая реальная программа (особенно работающая с сетью и потоками) — есть тонкое переплетение UB
В общем случае (если ничего не знать о том, откуда берётся buf) есть потенциальная возможность для невыровненного доступа. Если buf — это указатель на буфер, выделенный malloc/new, или же указатель на массив объектов boost::uint32_t, то правильное выравнивание гарантируется.
Вариант с memcpy легален без оговорок, разве что приведение &packetSize к void* излишне.
Здравствуйте, achp, Вы писали:
A>В общем случае (если ничего не знать о том, откуда берётся buf) есть потенциальная возможность для невыровненного доступа. Если buf — это указатель на буфер, выделенный malloc/new, или же указатель на массив объектов boost::uint32_t, то правильное выравнивание гарантируется.
Здравствуйте, Посторонним В., Вы писали:
ПВ>По сети я получаю пакет само собой в виде нетипизированного char-буфера. Формат пакета таков: в первых 4 байтах идет размер (unit32), потом уже сам пакет.
Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию.
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию.
Здравствуйте, remark, Вы писали:
V>>Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию. R>???
Ну, в настройках думаю может быть вполне, к примеру, как выгружать/загружать в/из памяти short/int/long, это опять же зависит от платформы, только тут скорее уже C-компиляторы. R>Есть такие компиляторы
Это вопрос или утверждение?
R>
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, remark, Вы писали:
V>>>Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию. R>>??? V>Ну, в настройках думаю может быть вполне, к примеру, как выгружать/загружать в/из памяти short/int/long, это опять же зависит от платформы, только тут скорее уже C-компиляторы.
Верится с трудом.
R>>Есть такие компиляторы V>Это вопрос или утверждение?
Здравствуйте, remark, Вы писали:
V>>>Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию. R>>??? V>Ну, в настройках думаю может быть вполне, к примеру, как выгружать/загружать в/из памяти short/int/long, это опять же зависит от платформы, только тут скорее уже C-компиляторы. R>Верится с трудом.
Почему?
R>>>Есть такие компиляторы V>>Это вопрос или утверждение? R>Это вопрос: Есть такие компиляторы?
А почему нет?
R>>> R>
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, remark, Вы писали:
V>>>>Есть ещё одна проблема, тип int/long может быть и не little endian, это в общем зависит от компилятора и платформы, поэтому приравнивание лучше заменить на функцию. R>>>??? V>>Ну, в настройках думаю может быть вполне, к примеру, как выгружать/загружать в/из памяти short/int/long, это опять же зависит от платформы, только тут скорее уже C-компиляторы. R>>Верится с трудом. V>Почему?
R>>>>Есть такие компиляторы V>>>Это вопрос или утверждение? R>>Это вопрос: Есть такие компиляторы? V>А почему нет?
Имхо, абсурдно тут идти против платформы
R>>>> R>>
Здравствуйте, remark, Вы писали:
R>Имхо, абсурдно тут идти против платформы
Почему против? А если сама платформа предоставляет такие возможности?
R>>>>> R>>> R>
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, remark, Вы писали:
R>Это вопрос: Есть такие компиляторы?
В принципе, а почему бы и нет? Если процессор чисто 16-битный — то запросто. Например, 8086 или PDP-11.
Порядок вордов в дворде там обуславливается только традициями и предпочтениями.
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, remark, Вы писали:
R>>Это вопрос: Есть такие компиляторы?
К>В принципе, а почему бы и нет? Если процессор чисто 16-битный — то запросто. Например, 8086 или PDP-11. К>Порядок вордов в дворде там обуславливается только традициями и предпочтениями.
Здравствуйте, remark, Вы писали:
К>>В принципе, а почему бы и нет? Если процессор чисто 16-битный — то запросто. Например, 8086 или PDP-11. К>>Порядок вордов в дворде там обуславливается только традициями и предпочтениями.
R>А сложение как там работает?
Как нефиг делать.
; dx:ax - число в регистрах
; dword ptr[si] - число в памяти, адрес - в регистре si
add ax, word ptr [si+4] ; сложили младшие ворды
adc dx, word ptr [si+0] ; сложили старшие ворды с переносом
Здравствуйте, Кодт, Вы писали:
К>Здравствуйте, remark, Вы писали:
К>>>В принципе, а почему бы и нет? Если процессор чисто 16-битный — то запросто. Например, 8086 или PDP-11. К>>>Порядок вордов в дворде там обуславливается только традициями и предпочтениями.
R>>А сложение как там работает?
К>Как нефиг делать. К>
К>; dx:ax - число в регистрах
К>; dword ptr[si] - число в памяти, адрес - в регистре si
К>add ax, word ptr [si+4] ; сложили младшие ворды
К>adc dx, word ptr [si+0] ; сложили старшие ворды с переносом
К>
Этот код не может работать с разным порядком байт в слове.
Если add работает более чем с одним байтом, то ему *нужно* знать в каком порядке там лежат байты.
Или я совсем что-то не понимаю.
Ядро же должно знать из какого байта слова в какой делать перенос.
Здравствуйте, remark, Вы писали:
A>>Э... И чего? Совмещение миён здесь проблемой не является ни при каких обстоятельствах. А вот выравнивание под вопросом.
R>Во-первых, вопрос про aliasing.
Цитата:
После прочтения недавно обсуждавшейся темы про strict aliasing засомневался, правильно ли я делаю.
...
boost::uint32_t packetSize = *(boost::uint32_t*)(buf);
...
Что тут указвает на то, что вопрос именно про aliasing?
ИМХО вопрос о правильности вообще
R>Во-вторых, буфер-то он сам выделял, значит, наверное, в курсе на сколько он выровнен.
Ключевое слово "наверное". Лично я сильно сомневаюсь, что кто-то будет специально следить за выравниванием char-буфера.
Конечно, если буфер выделяется с помощью new[], то проблем с выравниванием не будет. А если как-то по-другому? А если buf указывает внутрь другого char-буфера?
Конечно о том, как оно в данном случае на самом деле, пусть скажет автор.
Здравствуйте, remark, Вы писали:
R>Этот код не может работать с разным порядком байт в слове. R>Если add работает более чем с одним байтом, то ему *нужно* знать в каком порядке там лежат байты. R>Или я совсем что-то не понимаю. R>Ядро же должно знать из какого байта слова в какой делать перенос.
Так перед любой операцией операнды неявно в регистры должны сначало копироваться, а в регистрах всегда представлено в какомто одном виде, разница имеется только при загрузке и выгрузке.
R>
[In theory there is no difference between theory and practice. In
practice there is.]
[Даю очевидные ответы на риторические вопросы]
Здравствуйте, Vain, Вы писали:
V>Здравствуйте, remark, Вы писали:
R>>Этот код не может работать с разным порядком байт в слове. R>>Если add работает более чем с одним байтом, то ему *нужно* знать в каком порядке там лежат байты. R>>Или я совсем что-то не понимаю. R>>Ядро же должно знать из какого байта слова в какой делать перенос. V>Так перед любой операцией операнды неявно в регистры должны сначало копироваться, а в регистрах всегда представлено в какомто одном виде, разница имеется только при загрузке и выгрузке.