Boost C++ Libraries: Ticket #9843: binary serializer wrong behaviour treating enums https://svn.boost.org/trac10/ticket/9843 <p> from iserializer.hpp template&lt;class Archive&gt; struct load_enum_type { </p> <blockquote> <p> template&lt;class T&gt; static void invoke(Archive &amp;ar, T &amp;t){ </p> <blockquote> <p> <em> convert integers to correct enum to load int i; ar &gt;&gt; boost::serialization::make_nvp(NULL, i); t = static_cast&lt; T &gt;(i); </em></p> </blockquote> <p> } </p> </blockquote> <p> }; </p> <p> it tries to load all enums int-sized. even in this case: enum class <a class="missing wiki">WrongBehaviour</a> : unsigned char { }; </p> <p> it reads 4-byte in my case, while 1 byte's expected. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/9843 Trac 1.4.3 Robert Ramey Mon, 07 Apr 2014 15:57:17 GMT status changed; resolution set https://svn.boost.org/trac10/ticket/9843#comment:1 https://svn.boost.org/trac10/ticket/9843#comment:1 <ul> <li><strong>status</strong> <span class="trac-field-old">new</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> Hmmm - this would be quite surprising after many years. </p> <p> Are you're using exactly the same platform for de-serialization as for serialization? Remember that the binary archive is explicitly defined not to be portable in the interests of performance. I would need a better test case to justify spending more time on this. </p> <p> Robert Ramey </p> Ticket jpjps@… Thu, 10 Apr 2014 07:09:22 GMT status changed; resolution deleted https://svn.boost.org/trac10/ticket/9843#comment:2 https://svn.boost.org/trac10/ticket/9843#comment:2 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> <p> simple snippet: </p> <pre class="wiki"> enum class SyncCode : unsigned char { ProcessId, ModuleFileName, }; std::ostringstream stream; binary_oarchive archive(stream, boost::archive::no_header); archive &lt;&lt; SyncCode::ProcessId; auto firstSize = stream.str().size(); stream = std::ostringstream(); archive &lt;&lt; (unsigned char)SyncCode::ProcessId; auto secondarySize = stream.str().size(); </pre><p> firstSize results 4, secondarySize 1. on vs2013 / windows8.1 x64, targeted x86. </p> <p> simple trick works on this case: </p> <pre class="wiki">//oserializer.hpp template&lt;class Archive&gt; struct save_enum_type { template&lt;unsigned char TypeSize&gt; struct same_sized_integral_type; // undefined template&lt;&gt; struct same_sized_integral_type&lt;1&gt; { typedef unsigned char type; }; template&lt;&gt; struct same_sized_integral_type&lt;2&gt; { typedef unsigned short type; }; template&lt;&gt; struct same_sized_integral_type&lt;4&gt; { typedef unsigned int type; }; template&lt;&gt; struct same_sized_integral_type&lt;8&gt; { typedef unsigned long long type; }; template&lt;class T&gt; static void invoke(Archive &amp;ar, const T &amp;t){ // convert enum to integers on save const same_sized_integral_type&lt;sizeof(T)&gt;::type i = static_cast&lt;same_sized_integral_type&lt;sizeof(T)&gt;::type&gt;(t); ar &lt;&lt; boost::serialization::make_nvp(NULL, i); } }; </pre> Ticket anonymous Thu, 10 Apr 2014 08:06:33 GMT <link>https://svn.boost.org/trac10/ticket/9843#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9843#comment:3</guid> <description> <p> ahh, I finally figured out... there were some extensions of mine. to enable ability to serialize of literals: </p> <pre class="wiki"> //interface_oarchive.hpp template&lt;class T&gt; Archive &amp; operator&lt;&lt;(const T &amp;&amp; t){ return *this-&gt;This() &lt;&lt; t; } </pre><p> it could be considered not a problem of 'original' boost. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Thu, 10 Apr 2014 08:37:16 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/9843#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9843#comment:4</guid> <description> <p> brought more straightfoward case: </p> <pre class="wiki"> enum class PacketCode : unsigned char { Something, }; PacketCode packetcode; //no exception std::istringstream stream(std::string(4, 0)); binary_iarchive archive(stream, boost::archive::no_header); archive &gt;&gt; packetcode; //exception. it tries to read 4 bytes stream = std::istringstream(std::string(1, 0)); archive &gt;&gt; packetcode; </pre> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Fri, 11 Apr 2014 01:44:49 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/9843#comment:5 https://svn.boost.org/trac10/ticket/9843#comment:5 <ul> <li><strong>status</strong> <span class="trac-field-old">reopened</span> → <span class="trac-field-new">closed</span> </li> <li><strong>resolution</strong> → <span class="trac-field-new">invalid</span> </li> </ul> <p> Hmmm, I would really, really, really have to think about using move here. Basically this would permit serialization of temporary objects which opens a whole can of worms regarding tracking. I think would also have to consider that using move might change the object being serialized - which would make another problem. </p> <p> Actually the usage of move semantics in the serialization library is likely an interesting question and could lead to better performance in some cases - e.g. collections. </p> <p> But for now, I think we're done with this. </p> <p> Robert Ramey </p> Ticket anonymous Mon, 14 Apr 2014 05:39:45 GMT <link>https://svn.boost.org/trac10/ticket/9843#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9843#comment:6</guid> <description> <p> I would really sorry for the confusion caused by my comments 2,3. I coudn't find any way to delete comments. </p> <p> But we should bring the original issue. The original one is that "boost binary archive does not consider of sized-enums. It treats all the enums as int-sized" as described in comment 4. </p> <p> So it causes some problems: </p> <pre class="wiki">// from iserializer.hpp, load_enum_type&lt;&gt;::invoke&lt;&gt;(...): int i; ar &gt;&gt; boost::serialization::make_nvp(NULL, i); // loads as "int" t = static_cast&lt; T &gt;(i); // convert it to "enum type" </pre><p> When T is such </p> <pre class="wiki">enum class PacketCode : unsigned char { Something, }; </pre><p> Again, I sorry for bothering you. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>anonymous</dc:creator> <pubDate>Mon, 14 Apr 2014 05:39:59 GMT</pubDate> <title>status changed; resolution deleted https://svn.boost.org/trac10/ticket/9843#comment:7 https://svn.boost.org/trac10/ticket/9843#comment:7 <ul> <li><strong>status</strong> <span class="trac-field-old">closed</span> → <span class="trac-field-new">reopened</span> </li> <li><strong>resolution</strong> <span class="trac-field-deleted">invalid</span> </li> </ul> Ticket Robert Ramey Mon, 14 Apr 2014 05:59:39 GMT <link>https://svn.boost.org/trac10/ticket/9843#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/9843#comment:8</guid> <description> <p> OK - I see the problem now. </p> <pre class="wiki">// works enum class PacketCode { Something, }; // doesn't work enum class PacketCode : unsigned char { Something, }; </pre><p> But I can't see where the problem is since the load and save functions both confer to/from integers the serialization should be in sync. Your original complaint says that it's saving one byte and reading back 4. The file oserializer.hpp contains: </p> <pre class="wiki">template&lt;class Archive&gt; struct save_enum_type { template&lt;class T&gt; static void invoke(Archive &amp;ar, const T &amp;t){ // convert enum to integers on save const int i = static_cast&lt;int&gt;(t); ar &lt;&lt; boost::serialization::make_nvp(NULL, i); } }; </pre><p> I'm guessing I did this because the streams didn't accept an enum. If you would like, you can make a test case similar to the ones in the test suite and submit a patch. I'd be willing to consider it. </p> <p> Robert Ramey </p> </description> <category>Ticket</category> </item> </channel> </rss>