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

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> boost::serialization ? баг : фича, Или чем А.Пугачёва лучше Ф.Киркорова :) 
:(
    Опции темы
volatile
Дата 4.2.2011, 01:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Сначала небольшой материал:
Код

#include "stdafx.h"
#include <fstream>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <string>

class test // Наш небольшой класс, который хранит имя и возраст.
{
    friend class boost::serialization::access;
    template<class Archive>
    void serialize(Archive & ar, const unsigned int version)
    {
        ar & name;
        ar & age;
    }
    std::wstring name; // Имя
    int age;           // Возраст
public:
    test () {;}
    test (const std::wstring &n, int a) : name(n), age(a) {;}
    bool operator==(const test& v) {return name==v.name && age==v.age;} // Это для стравнения
};
BOOST_CLASS_TRACKING(test, boost::serialization::track_never); // Это чтоб ворингов не было

int _tmain(int argc, _TCHAR* argv[])
{
   test a(L"Алла Пугачёва", 60); // Наши данные, их будем сериализовать.
   test b; // Сюда будем читать.
   
   {  // Сериализуем в файл наши данные
      std::ofstream ofs("name.txt", std::ios::out);
      boost::archive::text_oarchive oa(ofs);
      oa << a;
   }

   {  // Читаем наши данные из файла в другую переменную 
      std::ifstream ifs("name.txt", std::ios::in);
      boost::archive::text_iarchive ia(ifs);
      ia >> b;
   }
   //Проверяем на соответствие.
   std::cout << (b==a ? "Good" : "Bad") ;
   return 0;
}

Итак запускаем программку.
Выводит: "Good". Хорошо!.

Теперь вместо "Алла Пугачёва", вбиваем "Филипп Киркоров"
Запускаем... и тут ... нас ждёт неожиданный эксцепшн "stream error"!
Мы не поменяли ничего в программе, только данные изменились.
Я долго не мог понять, почему?!!

Оказывается дело в том что в юникодной кодировке, русская буква "К" имеет код 0x041A
а байт с кодом 1A буст воспринимает за конец файла.
Если бы не было дальнейшего вывода после имени, (а я специально для наглядности вывел здесь возраст),
то и исключения бы не было, просто считалось бы "Филипп " и всё, без "Киркорова" и без ксцепшна. smile

Не знаю это баг, или фича. Скорее все-же баг. Потому-что, если буст не поддреживает юникод, то и тип wstring поддерживать не нужно.
А вообще все работает нормально, с любым юникодным текстом, но только до тех пор, пока не встретится большая русская буква "К".
Теперь буду работать с бинарным выводом.
Прошу комментировать.

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Ну все давно поняли что Киркоров нехороший человек. Вон даже boost об него спотыкается  smile 
PM MAIL WWW   Вверх
kemiisto
  Дата 4.2.2011, 01:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Дикий Кот. =^.^=
****
Награды: 1



Профиль
Группа: Участник Клуба
Сообщений: 3292
Регистрация: 29.7.2007

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



Цитата(volatile @  3.2.2011,  23:39 Найти цитируемый пост)
Не знаю это баг, или фича. Скорее все-же баг. 

Как ты смеешь, негодяй!? Это фича. Какие баги могут быть в величайшем творении человечества!? Да снизойдёт на тебя кара небесная, мерзавец!

Цитата(volatile @  3.2.2011,  23:39 Найти цитируемый пост)
Прошу комментировать.

Да тут, собственно, нечего комментировать.

user posted image

Приятного аппетита!

Это сообщение отредактировал(а) kemiisto - 4.2.2011, 01:53


--------------------
PM MAIL WWW GTalk Jabber   Вверх
boostcoder
Дата 4.2.2011, 02:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



наверняка все же баг... но какой-то странный..

Цитата(volatile @  4.2.2011,  01:39 Найти цитируемый пост)
байт с кодом 1A буст воспринимает за конец файла.

буст большой. о какой именно части буста вы говорите?


зы
в жизни не использовал юникод, и не очень понимаю для чего он.
но раз, или два, использовал кириллицу, и на такой баг не напоролся.
PM WWW   Вверх
KaraKum
Дата 4.2.2011, 02:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Цитата(boostcoder @  4.2.2011,  03:40 Найти цитируемый пост)
о какой именно части буста вы говорите?

Речь идёт о сериализации.

Вот тут похожая проблема - видимо это не совсем баг - нужно попробовать boost::archive::binary_archive вместо boost::archive::text_oarchive.
PM MAIL WWW   Вверх
Alexeis
Дата 4.2.2011, 08:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

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



  А я недавно также напоролся на баг именно с юникодом. Тоже анси все ок, а точка юникода смерть. Грешил на билдер, но сейчас подумал, что новый билдер содержит обновление буста....


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
xvr
Дата 4.2.2011, 13:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Откройте выходной и входной файлы в бинарном режиме (в std::ofstream и std::ifstream добавить std::ios::binary) и не катите бочку на boost, он тут не пи чем  smile 

PM MAIL   Вверх
KaraKum
Дата 4.2.2011, 13:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Цитата(xvr @  4.2.2011,  14:38 Найти цитируемый пост)
не катите бочку на boost

А что мешало хвалёному бусту получить размер файла при его открытии для определения его окончания чтобы не напарываться вот на такие костыли??
PM MAIL WWW   Вверх
xvr
Дата 4.2.2011, 13:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(KaraKum @  4.2.2011,  13:40 Найти цитируемый пост)
А что мешало хвалёному бусту получить размер файла при его открытии для определения его окончания

Вы удивитесь, но файл будет короче, чем ожидалось  smile 
Проблема не в boost'е, а в файловом потоке, который открыли в текстовой моде (она такая по умолчанию). 
Вот тут:
Код

std::ofstream ofs("name.txt", std::ios::out);
// и тут
std::ifstream ifs("name.txt", std::ios::in);

А так же в том, что туда попытались записать (а потом прочесть) байт 1A. И файловый поток обрезал по 1A содержимое, а не boost  smile 

PM MAIL   Вверх
KaraKum
Дата 4.2.2011, 13:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Цитата(xvr @  4.2.2011,  14:49 Найти цитируемый пост)
Вы удивитесь, но файл будет короче, чем ожидалось

Что?
PM MAIL WWW   Вверх
xvr
Дата 4.2.2011, 14:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(KaraKum @ 4.2.2011,  13:51)
Цитата(xvr @  4.2.2011,  14:49 Найти цитируемый пост)
Вы удивитесь, но файл будет короче, чем ожидалось

Что?

Пример -
Код

#include <fstream>
#include <iostream>
#include <string>


int main()
{
  {
   std::ofstream ofs("name.txt", std::ios::out);

   ofs<<"TestStrng" "\x1A" "eriuwiorwodjdkcdmncv"<<std::endl;
  }
  {
   std::ifstream ifs("name.txt", std::ios::in);

   while(ifs)
    {
     std::string s;
     getline(ifs,s);
     std::cout << s << std::endl;
     std::cout << s.size() << std::endl;
    }

  }

 return 0;
}


VS2008

Результат -
Цитата
TestStrng
9

0
Как видим хвост после 1A беследно исчез (хотя в файл 'name.txt' и записался, хотя был в праве обрезаться уже там)


Это сообщение отредактировал(а) xvr - 4.2.2011, 14:28
PM MAIL   Вверх
KaraKum
Дата 4.2.2011, 14:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Пример полный и понятный. Спасибо.
Получается мы перекладываем вину с boost'а на std, что не освобождает boost от ответственности, которого можно привлечь за бездействие  smile 

Это сообщение отредактировал(а) KaraKum - 4.2.2011, 14:44
PM MAIL WWW   Вверх
boostcoder
Дата 4.2.2011, 14:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


pattern`щик
****


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

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



я так понял, что в текстовом моде, код 1A, не является валидным.
PM WWW   Вверх
KaraKum
Дата 4.2.2011, 14:53 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Это буква "К" - что в ней невалидного?
http://www.unicode.org/charts/PDF/U0400.pdf
PM MAIL WWW   Вверх
xvr
Дата 4.2.2011, 14:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(boostcoder @ 4.2.2011,  14:48)
я так понял, что в текстовом моде, код 1A, не является валидным.

Почему же, это вполне валидный признак конца файла  smile Ноги у этого 1A растут еще из CPM (была такая ОС, предшественник MSDOS). В CPM длинна файла определялась количеством блоков в нем (по 128 байт). Частичные блоки не поддерживались. Поэтому, что бы в текстах не было мусора в конце (до границы 128ми байтового блока), и был зарезервирован специальный код (1A), для обозначения конца данных в файле

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


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



А вот интересно - зачем нужен вообще этот символ? Ведь стандартная C библиотека позволяет определить размер файла:
Код

  // obtain file size:
  fseek (pFile , 0 , SEEK_END);
  lSize = ftell (pFile);
  rewind (pFile);

Почему бы std::ifstream не определить в конструкторе размер файла и не обрабатывать каждое чтение согласно этому размеру?
Неужели это для совместимости с CPM?  smile 

Это сообщение отредактировал(а) KaraKum - 4.2.2011, 15:19
PM MAIL WWW   Вверх
xvr
Дата 4.2.2011, 16:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Цитата(KaraKum @  4.2.2011,  15:18 Найти цитируемый пост)
А вот интересно - зачем нужен вообще этот символ? Ведь стандартная C библиотека позволяет определить размер файла:
Его и ifstream определить может (через seekg/tellg), и правильно определяет, но не читает до конца - поток переходит в EOF состояние ДО достижения реального конца в файле. Кстати, со стандартной С библиотекой те же самые грабли - она тоже не станет читать дальше 1A (хоть размер и определит)

Цитата(KaraKum @  4.2.2011,  15:18 Найти цитируемый пост)
Неужели это для совместимости с CPM?
По сути - да  smile 


PM MAIL   Вверх
KaraKum
Дата 4.2.2011, 16:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 640
Регистрация: 3.12.2007

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



Цитата(xvr @ 4.2.2011,  17:33)
Цитата(KaraKum @  4.2.2011,  15:18 Найти цитируемый пост)
Неужели это для совместимости с CPM?
По сути - да  smile

Ужас какой.
И долго ещё нас будут преследовать эти окаменелости наших до-POSIX предков? smile 
PM MAIL WWW   Вверх
volatile
Дата 4.2.2011, 23:27 (ссылка) |    (голосов:2) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Да всё это понятно что это старая проблема, но буст громко заявляет что его сериализация будет считываться правильно на любых машинах, в том числе даже с обратным порядком байтов (Little endian) (Big endian) и т.д. и т.п.
Это конечно к данной проблеме не относится напрямую, но разработчики могли бы учесть и этот момент и передавать байт 1A в текстовом виде (например что-то типа "%1A", как в адресной строке браузера, например).
В любом случае, все эти библиотеки пишут люди далёкие от проблем локализации.

Больше всего не приятно, что этот баг проявляется тихо и редко. Когда выложена такая маленькая программка, то все понятно, конечно. А если большой проект, и там где-то внутри, иногда, непонятно от чего вылетает непонятно что, долго придется ломать голову, и валить на неполадки в питании, микросхемы памяти, фазы луны...

PM MAIL   Вверх
mes
Дата 5.2.2011, 00:47 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


любитель
****


Профиль
Группа: Участник Клуба
Сообщений: 7954
Регистрация: 14.1.2006

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



Цитата(volatile @  4.2.2011,  22:27 Найти цитируемый пост)
Да всё это понятно что это старая проблема, но буст громко заявляет что его сериализация будет считываться правильно на любых машинах, в том числе даже с обратным порядком байтов (Little endian) (Big endian) и т.д. и т.п.

для бинарного потока данных, а не для текстового.. на последний есть свои правила и ограничения (и 0х1а не единственный в своем роде),  в следствии чего он просто не применим для подобных целей.. 


Это сообщение отредактировал(а) mes - 5.2.2011, 00:49


--------------------
PM MAIL WWW   Вверх
volatile
Дата 5.2.2011, 01:43 (ссылка) |    (голосов:4) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


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

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



Но, тем не менее разработчики оказывается осведомлены об этом баге, и общеают в будущем исправиться, выводя код EOF ескейп-последовательностями:

Цитата
Pending issues
...
•Its possible that std::string and std::wstring contain characters such as '\0' and -1 (EOF) which cannot be rendered in text and XML archives without an escape mechanism. Currently there is no such escape mechanism implemented. 


Добавлено @ 01:53
Да, вот линк, где это написано.
http://www.boost.org/doc/libs/1_45_0/libs/...oc/release.html

Так что не все так плохо, и когда-нибудь будет совсем хорошо. smile


Это сообщение отредактировал(а) volatile - 5.2.2011, 01:56
PM MAIL   Вверх
xvr
Дата 5.2.2011, 16:41 (ссылка)  | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 7046
Регистрация: 28.8.2007
Где: Дублин, Ирландия

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



Это как бы не баг, это фича  smile Программист должен понимать, что он делает. Если открыть на запись /dev/null и дать бусту он тоже туда все замечательно сериализует. Или boost должен это тоже отлавливать и писать куда нибудь в другое место?  smile 

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


pattern`щик
****


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

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



Цитата(xvr @  5.2.2011,  16:41 Найти цитируемый пост)
Это как бы не баг, это фича

не баг. но очень провоцирует.
PM WWW   Вверх
Страницы: (2) [Все] 1 2 
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
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.1008 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


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

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