LINUX.ORG.RU

Необходимость в такой конструкции.

 ,


0

2

В коде часто натыкаюсь на конструкции вида:

tmp = htonl(bufs[imf]);
if( memcpy(buf, &tmp, sizeof(unsigned long)) < 0) {
    p_syslog(LOG_ERR, "memcpy imf");
    err=1;
}
такой участок можно заменить на:
*((unsigned long)buf) = htonl(bufs[imf]);

И если я прав, в чем мог был смысл memcpy, если мы копируем просто примитив?

А кто тебе сказал, что buf всегда будет выровнен по размеру unsigned long? Многие архитектуры невыровненный доступ к словам вообще не разрешают. На ia32 оно просто тормозить будет, на MIPS или на Sparc трапнется.

anonymous
()
Ответ на: комментарий от anonymous

anonymous

А кто тебе сказал, что buf всегда будет выровнен по размеру unsigned long?

Если ты про выделение памяти, buf размечается через malloc в 1024 байта. В программе, в том числе много такого кода:

char *buf;
*((unsigned long *)buf) = htonl(some_long_value);
*((unsigned short *)(buf+sizeof(unsigned long))) = htons(some_short_value);

andreykyz ★★
() автор топика
Ответ на: комментарий от andreykyz

Если ты про выделение памяти, buf размечается через malloc в 1024 байта. В программе, в том числе много такого кода:

Сам по себе (buf) может быть и выровнен как надо, а вот (buf + sizeof(что_то)) уже может залезть на границу.

Deleted
()
Ответ на: комментарий от andreykyz

Нет, про выравнивание. То есть, значение адреса buf должно быть кратно 4 или 8 (что там у тебя long). Это далеко не всегда так, потому и необходимо использовать memcpy.

anonymous
()
Ответ на: комментарий от Deleted

Если buf выровнен по sizeof(что-то), то и buf+sizeof(что-то) будет так же выровнен.

А вот если там протокол хитрый, например, идут byte + byte + word + byte, то этот самый word будет невыровненным.

anonymous
()
Ответ на: комментарий от andreykyz

Вообще, по хорошему, за любую конструкцию вида *((some_integral_type *)buf) = ... надо отрывать руки. Потому как это, согласно стандарту, undefined behaviour в случае невыровненного указателя. Поскольку buf определен как char*, он может быть выровнен как угодно.

anonymous
()

бро, это или херня какая-то или у тебя хитрожопый memcpy

if( memcpy

man memcpy

void *memcpy(void *dest, const void *src, size_t n);

ВОЗВРАЩАЕМЫЕ ЗНАЧЕНИЯ

Функция memcpy() возвращает указатель на dest.

ckotinko ☆☆☆
()
Ответ на: комментарий от anonymous

Если buf выровнен по sizeof(что-то), то и buf+sizeof(что-то) будет так же выровнен.

А вот если там протокол хитрый, например, идут byte + byte + word + byte, то этот самый word будет невыровненным.

Да, я неточно выразился.

Deleted
()

Отрицательные указатели? Это что-то новое.

Sorcerer ★★★★★
()
Ответ на: комментарий от anonymous

anonymous

Вообще, по хорошему, за любую конструкцию вида *((some_integral_type *)buf) = ... надо отрывать руки.

Дело в том я что я сейчас и занимаюсь тем что переделываю такие конструкции, на структуры.

anonymous

Поскольку buf определен как char*, он может быть выровнен как угодно.

каким образом выровнять, чтобы работало и на x86 и на MIPS? По сути сейчас в buf хранятся только uint16_t и uint32_t.

andreykyz ★★
() автор топика
Ответ на: комментарий от andreykyz

на структуры

За пакованые структуры тоже надо руки отрывать. Не все компиляторы такие умные, кто-то может и UB получить.

каким образом выровнять, чтобы работало и на x86 и на MIPS? По сути сейчас в buf хранятся только uint16_t и uint32_t.

Ты не можешь записать 16bit и после сразу 32bit таким образом как ты хочешь. Вот если бы были только 16 или только 32 бита - другое дело. А так - только memcpy, только побайтовая запись в буфер.

anonymous
()
Ответ на: комментарий от anonymous

За пакованые структуры тоже надо руки отрывать. Не все компиляторы такие умные, кто-то может и UB получить.

У нас вполне конкретный компилятор gcc. Программа только под linux.

Ты не можешь записать 16bit и после сразу 32bit таким образом как ты хочешь.

На данный момент программа написана именно так и всё работает и на x86 и на MIPS. Объясни конкретнее.

andreykyz ★★
() автор топика
Ответ на: комментарий от andreykyz

«Именно так» - это как? С кастованием char* к long*? Не верю, оно трапнется.

И это не самое умное решение, на gcc рассчитывать. UB - оно такое, сегодня работает, завтра перестанет.

anonymous
()

fighting the lemmings

Deleted
()
Ответ на: комментарий от andreykyz

Кстати, еще от ОС зависит - некоторые это прерывание корректно обрабатывают (например, OpenVMS на Альфе обрабатывал, а Digital Unix трапался). Но в любом случае это адски медленно. Так что не выпендривайся и делай как стандарт велит.

anonymous
()
Ответ на: комментарий от anonymous

Кстати, еще от ОС зависит

может ещё на ресурсе об ОС Linux обсудим компиляцию при помощи Visual Studio 2012 под WIndows 8 на arm?

Так что не выпендривайся и делай как стандарт велит.

Ни одной ссылки от тебя не было. Только mironov_ivan запостил Fighting the Lemmings

andreykyz ★★
() автор топика
Ответ на: комментарий от anonymous

gcc далеко не единственный компилятор под linux. И я уж молчу про всякие embedded.

Кароч, понял, ты вообще не в теме. Я уточнял вполне конкретную архитектуру, ОС и компилятор. Ты толи слепой, толи конченный тролль. И продолжаешь сочинять страшилки про никому ненужные архитектуры и вспоминать что было 10 лет назад.

Если ты не в теме ненадо парить мозг.

andreykyz ★★
() автор топика
Ответ на: комментарий от andreykyz

Ну, короче, ты быдлокодер. Тех мразей, кто пишет под «конкретную архитектуру, ОС и компилятор» надо кастрировать ржавыми ножницами без наркоза. И, кстати, лошара, производительность невыровненного доступа - говно даже на x86. Он, конечно же, работает, на раз в десять медленнее чем memcpy. Ну да быдлокодеров обычно и это не останавливает.

anonymous
()
Ответ на: комментарий от anonymous

Похоже нашел то что надо: http://www.leonerd.org.uk/code/libpack/

Посоветовали на другом ресурсе, может кому-то пригодится.

Ну, короче, ты быдлокодер.

ТРО-ЛО-ЛО - ШКО-ЛО-ЛО

andreykyz ★★
() автор топика
Ответ на: комментарий от AptGet

Хотелось бы готовое решение, для упаковки структур, т.к. изобретение велосипедов ненужно. Нашел вот ещё что http://code.google.com/p/protobuf-c/.

Про выравнивание уже сказали,

дело в том что, ещё нужно конвертировать в сетевую(или любую другую) нотацию чтобы все нормально работало при передаче по сети между разными host системами(big/little endian)

Я бы был согласен на использование выровненных структур, но как их передавать по сети, для меня пока вопрос. т.к. на разных архитектурах выровнено будет по разному. Так же непонятно сколько траффика по сети жрет эта сериализация.

andreykyz ★★
() автор топика
Ответ на: комментарий от andreykyz

О черт.... тысячи/сотни тысяч раз обсуждалось КАК сделать что бы хтонлы и нтохлы работали кроссплатформенно в твоем коде.

В любом мало мальски приличном учебнике по С это описано...

Jetty ★★★★★
()
Ответ на: комментарий от Jetty

Хотя можно и без нее, но это так - повыеживаться :)

Jetty ★★★★★
()
Ответ на: комментарий от andreykyz

Я бы был согласен на использование выровненных структур, но как их передавать по сети, для меня пока вопрос. т.к. на разных архитектурах выровнено будет по разному.

Поехавший? Это в памяти платформы они д. б. выровнены, ввод/вывод — только поэлементно и никак иначе.

anonymous
()
Ответ на: комментарий от anonymous

ввод/вывод — только поэлементно и никак иначе.

Ну зачем же так сразу... boost/serialization например есть.

Dudraug ★★★★★
()

Оп, а ты вообще знаком с выравниванием, ну с термином таким?

Dudraug ★★★★★
()
Ответ на: комментарий от Jetty

Jetty

О черт.... тысячи/сотни тысяч раз обсуждалось КАК сделать что бы хтонлы и нтохлы работали кроссплатформенно в твоем коде.

Каким образом запаковать структуру при помощи htonl htons? Да я знаю, сейчас ты предложешь очередной самописный велосипед. Например передавать как строку и использовать терминатор.

У кого-нибудь есть отзывы о protobuf ?

andreykyz ★★
() автор топика
25 февраля 2013 г.
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.