Boost C++ Libraries: Ticket #11245: Deserialization with private constructor works in 1.57 not in 1.58 https://svn.boost.org/trac10/ticket/11245 <p> Under certain circumstances deserialization of a class with a private constructor does not work with Boost 1.58. In 1.57 it worked fine. The code in the attached file, when compiled with Visual Studio 2013, gives the following error message: </p> <p> c:\program files (x86)\vc\include\xmemory0(588): error C2248: 'A::A' : cannot access private member declared in class 'A' </p> <p> 1&gt; c:\projects\serializetest\serializetest.cpp(14) : see declaration of 'A::A' </p> <p> 1&gt; c:\projects\serializetest\serializetest.cpp(9) : see declaration of 'A' </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/11245 Trac 1.4.3 anonymous Tue, 28 Apr 2015 19:22:13 GMT attachment set https://svn.boost.org/trac10/ticket/11245 https://svn.boost.org/trac10/ticket/11245 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">boost.cpp</span> </li> </ul> Ticket Stefan Hoelldampf <stefan.hoelldampf@…> Sat, 02 May 2015 10:01:17 GMT cc set https://svn.boost.org/trac10/ticket/11245#comment:1 https://svn.boost.org/trac10/ticket/11245#comment:1 <ul> <li><strong>cc</strong> <span class="trac-author">stefan.hoelldampf@…</span> added </li> </ul> <p> The same error here on Fedora 21 with gcc-4.9.2. </p> <p> I think the problem is related to the fact that load() in boost/serialization/vector.hpp calls detail::is_default_constructible&lt;U&gt;(), but it does not check whether the default constructor is accessible. </p> <p> Eventually, std::vector::resize() fails. </p> Ticket Robert Ramey Sat, 02 May 2015 14:17:32 GMT <link>https://svn.boost.org/trac10/ticket/11245#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11245#comment:2</guid> <description> <p> Turns out that I've had to look into the serialization of std::vector due to an unrelated issue. Here is what I found: </p> <p> serialization of a type with a private constructor will fail if that constructor needs to be called. </p> <p> But that often doesn't happen: </p> <p> a) on most common serialization the type is already created and just "filled in" by the load. </p> <p> b) when serialized through a pointer, the same type will fail as this requires that a new instance be created. </p> <p> c) An interesting case is std::vector the manner of loading is dependent on the result of the is_default_constructible type_trait. So I'd have to look at that again to see the effect of a constructor being private. </p> <p> This is even worse as the implementation of "is_default_constructible" is buggy in some compilers, and in others its correct but marked as buggy by boost/config.hpp. </p> <p> Now that I know all this, I'm inclined to take another look. On one hand, I'm tempted to also check the size of the vector, if it's already big enough then I could just fill it in if it's not could fill in what I can and append to the end. On the other hand, that would introduce non-obvious quirky runtime behavior which I generally like to avoid. The current system always works or always fails at compile time. </p> <p> Feel free to think about this some more and get back to me. I'll leave the ticket open for now. </p> </description> <category>Ticket</category> </item> <item> <author>Tony Lewis <tonyelewis@…></author> <pubDate>Wed, 06 May 2015 11:38:37 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/11245 https://svn.boost.org/trac10/ticket/11245 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">not_default_constructible.cpp</span> </li> </ul> <p> Shows v1.58.0 compilation failure on attempt to serialize vector of non-default-constructible class </p> Ticket Tony Lewis <tonyelewis@…> Wed, 06 May 2015 12:18:27 GMT <link>https://svn.boost.org/trac10/ticket/11245#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11245#comment:3</guid> <description> <p> Extra information... </p> <p> This problem doesn't just affect classes with private constructors; I'm finding it also breaks compilation for serialization of vectors of classes without default constructors (but with suitable <code>load_construct_data()</code> specializations). </p> <p> I've attached code (<a class="attachment" href="https://svn.boost.org/trac10/attachment/ticket/11245/not_default_constructible.cpp" title="Attachment 'not_default_constructible.cpp' in Ticket #11245">attachment:not_default_constructible.cpp</a><a class="trac-rawlink" href="https://svn.boost.org/trac10/raw-attachment/ticket/11245/not_default_constructible.cpp" title="Download">​</a>) that compiles cleanly under v1.57.0: </p> <pre class="wiki">g++ -std=c++1y -c -o ndc.o -isystem /opt/boost_1_57_0_gcc_build/include -ftemplate-backtrace-limit=0 not_default_constructible.cpp clang++ -std=c++1y -stdlib=libc++ -c -o ndc.o -isystem /opt/boost_1_57_0_clang_build/include -ftemplate-backtrace-limit=0 not_default_constructible.cpp </pre><p> ...but that fails to compile under v1.58.0: </p> <pre class="wiki">g++ -std=c++1y -c -o ndc.o -isystem /opt/boost_1_58_0_gcc_build/include -ftemplate-backtrace-limit=0 not_default_constructible.cpp clang++ -std=c++1y -stdlib=libc++ -c -o ndc.o -isystem /opt/boost_1_58_0_clang_build/include -ftemplate-backtrace-limit=0 not_default_constructible.cpp </pre><p> Both GCC and Clang fail whilst compiling the call to the vector's <code>resize()</code> at line 90 of <code>boost/serialization/vector.hpp</code>. </p> <p> My hypothesis is as follows... The changes to <code>load()</code> in <code>boost/serialization/vector.hpp</code> since v1.57.0 introduce problems because they add code that requires the type to be default constructible. Though it's surrounded by an <code>if(detail::is_default_constructible&lt;U&gt;()){ [...] }</code>, I think that's insufficient to stop it getting compiled. If it's important to keep this separate code for default constructible types, perhaps some sort of traits/SFINAE/template-specialization approach is required? </p> <p> Many thanks to all who contribute effort to this. </p> </description> <category>Ticket</category> </item> <item> <author>visa.jokelainen@…</author> <pubDate>Wed, 20 May 2015 05:49:33 GMT</pubDate> <title>cc changed https://svn.boost.org/trac10/ticket/11245#comment:4 https://svn.boost.org/trac10/ticket/11245#comment:4 <ul> <li><strong>cc</strong> <span class="trac-author">visa.jokelainen@…</span> added </li> </ul> Ticket anonymous Wed, 20 May 2015 14:43:46 GMT <link>https://svn.boost.org/trac10/ticket/11245#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11245#comment:5</guid> <description> <p> Note that in the version in the develop branch, I altered the implementation so that it only generates code actually used. This fixes the problem on my Clang, GCC compilers. So I believe the problem is "addressed". However, it does leave the confusion that occurs with a private ctor. That is, the error message refers to a private ctor which is a little misleading. </p> <p> Note that the issue of loading type T with a private default cort or not default constructible are related. That is the former implies the latter. This seems obvious in retrospect but certainly got me confused. </p> <p> I'm also thinking that loading a vector&lt;T&gt; where T is not default constructible should probably be called as a compile time error even though it could pass at runtime using the "fill-in" idea above. </p> <p> Soooooo, all in all, I think that the deserialization a vector whose type is not default constructible should be considered an error even though previously it was OK. </p> </description> <category>Ticket</category> </item> <item> <author>Tony Lewis <tonyelewis@…></author> <pubDate>Wed, 20 May 2015 15:36:25 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/11245#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11245#comment:6</guid> <description> <p> I'm not sure I fully understand the argument in <a class="ticket" href="https://svn.boost.org/trac10/ticket/11245#comment:5" title="Comment 5">comment:5</a> but, FWIW, I'd vote that it's worth continuing to support serialization/deserialization of vector&lt;T&gt; for non-default-constructible T (as was previously supported in v1.57.0). </p> <p> Reasons: </p> <ul><li>AFAIK, the standard doesn't require T to be default-constructible, </li><li>the serialization library allows users to define how the library should serialize/deserialize their non-default-constructible types and </li><li>the library previously supported this in v1.57.0. </li></ul> </description> <category>Ticket</category> </item> <item> <dc:creator>Robert Ramey</dc:creator> <pubDate>Sat, 23 May 2015 18:58:24 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/11245#comment:7 https://svn.boost.org/trac10/ticket/11245#comment:7 <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">fixed</span> </li> </ul> Ticket visa.jokelainen@… Wed, 22 Jul 2015 12:41:07 GMT <link>https://svn.boost.org/trac10/ticket/11245#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/11245#comment:8</guid> <description> <p> Hi. </p> <p> Any idea whether this will be released with boost 1.59.0? </p> <p> -Visa </p> </description> <category>Ticket</category> </item> </channel> </rss>