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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> тип в байтах, значение типа в массиве байтов 
:(
    Опции темы
NYX
  Дата 30.5.2012, 14:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



Всем ку! Появилась необходимость писать в файл байты. И писать не просто байты, а поиметь возможность сделать на подобии "WriteFloat(float Value);", где функция просто запишет в файл все-провсе. Первым делом что пришло на ум это union. Учитывая загадочность спецификации С++ (во первых за неимением онной. Во вторых за неимением знания тех. англ) пришлось лазить по форумам. Ну ничего... вроди бы инфу найти удалося. Значит коварнейшие POD. Вроди бы, как бы, получается что.... char это POD, char[4] это не POD по той причине, что расположение ячеек может быть произвольным и... в случае если выделялка памяти не найдет место под целый массив, чейки так и пойдут в разнобой. Правильно ли я понимаю? Ладно, с union тайна, но есть еще шаблоны. Что бы не путаться во всяких там memcpy по месту необходимости, сварганил вот такой класс на шаблонах

Класс на шаблонах
Код

template <typename _Type> class type_bytes {
public:

    type_bytes() {
        memset(&Bytes, 0, sizeof (_Type));
    }

    void Set(_Type Variable) {
        memcpy(&Bytes, &Variable, sizeof (_Type));
    }

    unsigned char Get(unsigned int Index) {
        return Bytes[Index];
    }

    unsigned int Size() {
        return sizeof (_Type);
    }

private:
    unsigned char Bytes[sizeof (_Type)];
};


Ну и само собой его использование в функции WriteFloat(float Value)
Код

    FILE *FileHandle = fopen("float_hex.bin", "wb");
    type_bytes<float> TB;
    TB.Set(1.666);
    for (unsigned int Index = 0; Index < TB.Size(); Index++)
        fputc(TB.Get(Index), FileHandle);
    fclose(FileHandle);


Уважаемые знатоки! Вопрос тупой до безумия. Правильно?  smile 

Это сообщение отредактировал(а) NYX - 30.5.2012, 14:26
--------------------
'long long long' is too long for GC
PM   Вверх
boostcoder
Дата 30.5.2012, 14:46 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(NYX @  30.5.2012,  14:05 Найти цитируемый пост)
char[4] это не POD по той причине, что расположение ячеек может быть произвольным

нет. они располалаются подряд.
и да, это POD.

Цитата(NYX @  30.5.2012,  14:05 Найти цитируемый пост)
Правильно?

ну...можно сказать да))


но лучше бы ты union использовал)

PM WWW   Вверх
NYX
Дата 30.5.2012, 15:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



То есть мои предрассудки на счет этого кода ->
Код

union SomeAny {
    int Value;
    unsigned char Bytes[sizeof(int)];
}

Они лишние? Я просто не разу в своей жизни не дебажил программы на сях. В том смысле что с асмом ваще дело не имел, заморачивался одно время написанием шуточной ОС, с целью без цели. А разбором опкода С++ компиляций не занимался, не эксперементировал и не совсем в курсе всей подноготной.
Значит union вполне себе пригоже, и нет необходимости ИМЕННО В ТАКОМ случае использовать шаблоны? smile Дешевле выйдет. Шаблоны же вроди бы приведут к созданию классов в разных типах и память не сэкономят вовсе.

то есть данное условие всегда true?
Код

    unsigned char Array[4];
if (&Array[0] == ((&Array[1]) - 1))
    Beep(2000, 100);


Это сообщение отредактировал(а) NYX - 30.5.2012, 15:24
--------------------
'long long long' is too long for GC
PM   Вверх
boostcoder
Дата 30.5.2012, 15:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(NYX @  30.5.2012,  15:02 Найти цитируемый пост)
unsigned char Bytes[sizeof(int)];

тут все корректно.

по поводу остального - юзай union.

Добавлено через 39 секунд
Цитата(NYX @  30.5.2012,  15:02 Найти цитируемый пост)
то есть данное условие всегда true?

да, для char`ов smile
PM WWW   Вверх
math64
Дата 30.5.2012, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Шаблон
Код

template <typename _Type> union union_bytes {
    _Type Value;
    unsigned char Bytes[sizeof (_Type)];
};

сам по себе никакого кода не генерит (при условии что _Type - простой тип (int, double, и т.д.) или структура из простых типов без конструктора.
При условии, что там, где будешь читать порядок байтов и выравнивание те же самые.
Если _Type содержит указатели и/или виртуальные методы - так вообще сохранять нельзя.

PM   Вверх
boostcoder
Дата 30.5.2012, 15:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



правда, if какой-то странный)
PM WWW   Вверх
NYX
Дата 30.5.2012, 15:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



Да скобка лишняя smile У меня температура просто, я мальца не адекватный в написании, мелкие ошибки сыпятся   smile 
--------------------
'long long long' is too long for GC
PM   Вверх
borisbn
Дата 30.5.2012, 16:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(boostcoder @  30.5.2012,  15:20 Найти цитируемый пост)
да, для char`ов

для любых типов - да (там же нет ни одного приведения типов, а -1 делается для типизированного указателя)
Код

template< class T >
void foo() {
   T Array[ 2 ];
   if ( &Array[0] == ( (&Array[1]) - 1) )
      cout << "cool" << endl;
   else
      cout << "bad" << endl;
}

int main() {
   foo<char>();
   foo<short>();
   foo<int>();
   foo<std::string>();
}

Цитата

cool
cool
cool
cool

http://liveworkspace.org/code/9bac509c80ea...20181409c259323


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
boostcoder
Дата 30.5.2012, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



Цитата(borisbn @  30.5.2012,  16:04 Найти цитируемый пост)
а -1 делается для типизированного указателя

кстати да.
PM WWW   Вверх
NYX
Дата 30.5.2012, 18:16 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



В смысле для типизированного? В смысле (void*) не айс? Ну ваще его использовать как бы не планируется. Приведения тоже как бы не планируются... в данной части по крайней мере. Где вся телега с записью байт в файл.
--------------------
'long long long' is too long for GC
PM   Вверх
borisbn
Дата 30.5.2012, 18:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(NYX @  30.5.2012,  18:16 Найти цитируемый пост)
В смысле для типизированного? В смысле (void*) не айс?

к void* вообще нельзя применять адресную арифметику
я же имел в виду, что в приведённом примере нет приведения адреса к целому числу. Например такой код
Код

  unsigned char Array[4];
  unsigned int a_0 = (unsigned int)&Array[0];
  unsigned int a_1 = (unsigned int)&Array[1];
  if ( a_0 == a_1 - 1 )
     Beep(2000, 100);

будет работать только для char, unsigned char и bool (да и то только на 32-х битной системе). У Вас же в коде единица отнимается от указателя. и это - нормально.

а вообще-то, void* - не айс.


--------------------
Женщины отличаются от программистов тем, что у них чары состоят из стрингов
PM MAIL Jabber   Вверх
NYX
Дата 30.5.2012, 18:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



Ну да, это я понял. Окей. Непомерно огромное  спасибо вам за помосч! А ваще было бы конечно не плохо в этом всем подробности раздобыть. По традиции времен, попрошу ссыльцо какое нибудь про подноготную встроенных типов данных smile Если такое есть ваще в нете.
--------------------
'long long long' is too long for GC
PM   Вверх
volatile
Дата 31.5.2012, 00:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Цитата(NYX @  30.5.2012,  14:05 Найти цитируемый пост)
Вопрос тупой до безумия. Правильно? 

Правильно, только с серьезными ограничениями:
  • Записанные типы должны быть только POD. (например не вздумайте записывать в файл std::string, это ни к чему хорошему не приведет!)
  • Данные записанные в файл, непереносимы. т.е. они можгут быть корректно прочитаны только той-же самой программой, (скомпилированной тем-же самым компилятором, на той-же самой системе).

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


Бывалый
*


Профиль
Группа: Участник
Сообщений: 165
Регистрация: 9.1.2007
Где: Россия, Москва

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



volatile, разумеется про типы и запись данных в файл размером с тип машины это дадададада. А вот на счет POD счас в серьез задумался, можно ли как то ограничить КРУГ поступающих типов данных? Ну, как то провоерить. является ли данный тип встроенным или это юзертип? Никогда не задавался этим вопросом. Вот в PHP знаю есть такая фишка, можно сравнить тип данных...
гуголь гласит о #include <typeinfo> и typeid(t).name()
Но там же на первой ссылке нашел предупреждения о том что это ваще лучше не использовать для рабочего кода...
И допустим заюзать... еще одна задача для меня... ведь можно как то макросами задать выходную ошибку копилятора? Ну типо определить ошибку прямо непосредственно в модуле и что бы компилятор ее выдавал если чо?

Это сообщение отредактировал(а) NYX - 31.5.2012, 01:13
--------------------
'long long long' is too long for GC
PM   Вверх
baldina
Дата 31.5.2012, 01:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



есть проверка времени компиляции в boost boost::is_pod()
а вообще "писать байты" для простых типов (не содержащих указатели)) можно минуя всякие memcpy, просто write (&var, sizeof var)
какая разница где будет sizeof?
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.0586 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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