На свежую голову, спасибо мне говорить не за что, так как выигрыш в производительности небольшой, а вот с переносимостью теперь действительно могут быть проблемы, из-за выравнивания :-((
#pragma pack(1) вижу, но оно гарантирует что
однобайтовые переменные никогда не будут выравниваться, а вот про unsigned такой гарантии может и не быть…
Вам привести пример формата данных, в котором жестко задан порядок байт и этот порядок байт обратный сетевому? Ну GIF, например. Или вы это к тому, что все платформы, у которых сетевой порядок байт родной давно умерли? — тогда, конечно, да, незачем.
Что же вы думаете, я не добьюсь чтобы вы меня поняли :-))
У Вас там написано: LittleEndian(const LittleEndian<T> & t)
{
for (unsigned i = 0; i < sizeof(T); i++)
bytes[i] = t.bytes[i];
}
и BigEndian(const BigEndian<T> & t)
{
for (unsigned i = 0; i < sizeof(T); i++)
bytes[i] = t.bytes[i];
}
Нет никакого еще и htonl. htonl и ntohl делают ровно одно и тоже: если платформа как Intel, то они переворачивают байты, если сетевой порядок байт является для платформы родным, то они ничего не делают. Таким образом, получить порядок байт обратный сетевому, не зная платформу, с их помощью невозможно.
Идея такая:
1. заменить слово struct на union
2. Добавить T w; после массива — то есть поле базового типа, которое накладывается на массив.
3. В теле копирующих конструкторов
LittleEndian(const LittleEndian<T> & t) и
BigEndian(const BigEndian<T> & t)
вместо цикла написать w=t.w;
4. всё.
А причем здесь вообще ntohl и ntohs? здесь же вообще другой функционал! ntohl и ntohs позволяют получить данные в сетевом порядке байт независимо от платформы, но получить данные в порядке байт обратном сетевому независимо от платформы с их помощью не получится, а здесь можно и так и так!
А почему так? Вроде бы не важно в каком они порядке, присваивание одной переменной другой переменной того же типа по-любому идентично побайтовому копированию.
Офигеть… на этом сайте много фрилансеров и вот представьте заказчик вам говорит:
«Ну и что, что мы договаривались, что работать будет только ТУТ, а мне теперь надо, чтобы работало и ТАМ тоже… Я же тебе ЗАПЛАТИЛ!!! а ведь МОГ и не заплатить, у нас в стране вообще-то принято не платить...»
нравится да? третье сообщение в переписке ровно такое же.
Кому-то может так удобно, например, представьте что вы запустили что-то долговыполняющееся и отошли «покурить», по возвращении вы вы сразу видите, что можно было не отходить, так как оно завершилось через пять секунд после вашего ухода…
Я тоже… Обычно бывает так: передо мной стоит какая-то задача.
Я разбиваю ее на несколько пунктов выполняю все кроме одного, и благополучно выясняю, что последний пункт самый сложный, тогда я опять разделяю его на несколько подпунктов и история повторяется…
#pragma pack(1) вижу, но оно гарантирует что
однобайтовые переменные никогда не будут выравниваться, а вот про unsigned такой гарантии может и не быть…
Зачем было так писать
template<typename T>
struct LittleEndian
{
union {
unsigned char bytes[sizeof(T)];
T w;
}
...
}
когда можно написать так
template<typename T>
union LittleEndian
{
unsigned char bytes[sizeof(T)];
T w;
…
}
У Вас там написано:
LittleEndian(const LittleEndian<T> & t)
{
for (unsigned i = 0; i < sizeof(T); i++)
bytes[i] = t.bytes[i];
}
и
BigEndian(const BigEndian<T> & t)
{
for (unsigned i = 0; i < sizeof(T); i++)
bytes[i] = t.bytes[i];
}
И в чем разница?
1. заменить слово struct на union
2. Добавить T w; после массива — то есть поле базового типа, которое накладывается на массив.
3. В теле копирующих конструкторов
LittleEndian(const LittleEndian<T> & t) и
BigEndian(const BigEndian<T> & t)
вместо цикла написать w=t.w;
4. всё.
Для копирования из базовых типов или из одного вашего типа в другой ваш тип цикл конечно нужен.
template<typename T>
union LittleEndian
{
unsigned char bytes[sizeof(T)];
T w;
…
LittleEndian(const LittleEndian & t) {
w = t.w;
}
templateunion LittleEndian
{
unsigned char bytes[sizeof(T)];
T w;
…
LittleEndian(const LittleEndian & t) {
w = t.w;
}
«Ну и что, что мы договаривались, что работать будет только ТУТ, а мне теперь надо, чтобы работало и ТАМ тоже… Я же тебе ЗАПЛАТИЛ!!! а ведь МОГ и не заплатить, у нас в стране вообще-то принято не платить...»
нравится да? третье сообщение в переписке ровно такое же.
Да, мы в курсе, спасибо.
Я разбиваю ее на несколько пунктов выполняю все кроме одного, и благополучно выясняю, что последний пункт самый сложный, тогда я опять разделяю его на несколько подпунктов и история повторяется…