Boost C++ Libraries: Ticket #3472: Setting value_initialized<T> to a value when T is a top-level const https://svn.boost.org/trac10/ticket/3472 <p> There is no way to set value_initialized&lt;T&gt; object to the non-initialized value when T is a top-level const. I think there should be. </p> <p> While it is not allowed to set a const value to a value after construction, one can usually set it to a value at construction time. The value_initialized&lt;T&gt; has no way to do that. Adding a constructor to it, which would allow the value to be set to something other than its default value initialized state, would solve this problem for T when it is a top-level const. </p> <p> A practical use case is that value_initialized&lt;T&gt; might be used in a template class where T is a template parameter of that particular template class. If the end-user specifies that T is a top-level const, then an initial value for T passed to that template class's constructor can not be used to set a value_initialized&lt;T&gt; object to that value, making value_initialized&lt;T&gt; unusable in such a situation. </p> <p> Adding a constructor to value_initialized&lt;T&gt; would solve that problem. </p> en-us Boost C++ Libraries /htdocs/site/boost.png https://svn.boost.org/trac10/ticket/3472 Trac 1.4.3 niels_dekker Tue, 22 Sep 2009 05:19:26 GMT owner changed; cc set https://svn.boost.org/trac10/ticket/3472#comment:1 https://svn.boost.org/trac10/ticket/3472#comment:1 <ul> <li><strong>cc</strong> <span class="trac-author">niels_address_until_2010-10-10@…</span> added </li> <li><strong>owner</strong> changed from <span class="trac-author">No-Maintainer</span> to <span class="trac-author">Fernando Cacciola</span> </li> </ul> <p> Related discussion starts here: [Boost-users] [value_initialized] when T is const, <a class="ext-link" href="http://lists.boost.org/boost-users/2009/09/52139.php"><span class="icon">​</span>http://lists.boost.org/boost-users/2009/09/52139.php</a> </p> Ticket Edward Diener <eld@…> Wed, 23 Sep 2009 18:27:29 GMT attachment set https://svn.boost.org/trac10/ticket/3472 https://svn.boost.org/trac10/ticket/3472 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">value_init.patch</span> </li> </ul> <p> Patch to latest SVN implementing fix </p> Ticket niels_dekker Tue, 05 Jan 2010 21:56:30 GMT <link>https://svn.boost.org/trac10/ticket/3472#comment:2 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:2</guid> <description> <p> I still think your request is very reasonable. So I have just had another look at your proposed patch, which adds an explicit <code>value_initialized(T const&amp;)</code> constructor. But now I'm a <em>little</em> bit worried that the patch <em>might</em> cause some confusion or ambiguity between your proposed constructor and the existing copy-constructor of <code>value_initialized</code>. You know, a constructor with a single parameter could get <em>some compiler</em> confused, when generating an implementation-defined copy-constructor, <a class="ext-link" href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522094"><span class="icon">​</span>as you have have recently reported to Microsoft</a>. Moreover, I believe there might be use cases where ambiguity would occur, even without a compiler bug. </p> <p> So wouldn't it be wiser to add an extra parameter to your constructor, as a <em>tag</em> (similar to <code>std::allocator_arg_t</code> in the latest <a class="ext-link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf"><span class="icon">​</span>C++0x Draft</a>, section [memory]). Such a parameter might unambiguously specify that your constructor would <em>direct-initialize</em> the object, instead of doing value-initialization. I would propose to call the tag type <code>boost::direct_initialized_t</code>, and add the following lines to <a class="ext-link" href="https://svn.boost.org/svn/boost/trunk/boost/utility/value_init.hpp"><span class="icon">​</span>value_init.hpp</a>: </p> <pre class="wiki"> struct direct_initialized_t { }; const direct_initialized_t direct_initialized = direct_initialized_t(); </pre><p> Your constructor could then be defined as follows: </p> <pre class="wiki"> explicit value_initialized(T const &amp; arg, direct_initialized_t) { new (wrapper_address()) wrapper(arg); } </pre><p> What do you think? </p> </description> <category>Ticket</category> </item> <item> <author>Edward Diener <eld@…></author> <pubDate>Wed, 06 Jan 2010 01:11:19 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:3 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:3</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3472#comment:2" title="Comment 2">niels_dekker</a>: </p> <blockquote class="citation"> <p> I still think your request is very reasonable. So I have just had another look at your proposed patch, which adds an explicit <code>value_initialized(T const&amp;)</code> constructor. But now I'm a <em>little</em> bit worried that the patch <em>might</em> cause some confusion or ambiguity between your proposed constructor and the existing copy-constructor of <code>value_initialized</code>. You know, a constructor with a single parameter could get <em>some compiler</em> confused, when generating an implementation-defined copy-constructor, <a class="ext-link" href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522094"><span class="icon">​</span>as you have have recently reported to Microsoft</a>. Moreover, I believe there might be use cases where ambiguity would occur, even without a compiler bug. </p> <p> So wouldn't it be wiser to add an extra parameter to your constructor, as a <em>tag</em> (similar to <code>std::allocator_arg_t</code> in the latest <a class="ext-link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3000.pdf"><span class="icon">​</span>C++0x Draft</a>, section [memory]). Such a parameter might unambiguously specify that your constructor would <em>direct-initialize</em> the object, instead of doing value-initialization. I would propose to call the tag type <code>boost::direct_initialized_t</code>, and add the following lines to <a class="ext-link" href="https://svn.boost.org/svn/boost/trunk/boost/utility/value_init.hpp"><span class="icon">​</span>value_init.hpp</a>: </p> <pre class="wiki"> struct direct_initialized_t { }; const direct_initialized_t direct_initialized = direct_initialized_t(); </pre><p> Your constructor could then be defined as follows: </p> <pre class="wiki"> explicit value_initialized(T const &amp; arg, direct_initialized_t) { new (wrapper_address()) wrapper(arg); } </pre><p> What do you think? </p> </blockquote> <p> I think that doing such contortions to avoid a Microsoft bug is unwise. You are basically saying, as I see it, that adding the 'explicit value_initialized(T const &amp; arg)' along with the already existing copy constructor of 'value_initialized(value_initialized const &amp; arg)' is going to cause VC++ to call the wrong constructor when trying to copy a value-initialized value. As I understand the Microsoft bug the problem lies when Microsoft generates a user-defined copy constructor in a derived class and this calls down to the incorrect base class constructor. Unless someone is going to derive a class from value_initialized, which is probably not going to be done very often, my added constructor will not cause problems with VC++. Even when it does in that particular case, do you really believe that it should be necessary to contort C++ just to deal with a single compiler's problem ? I would much rather have the person who might consider deriving from value_initialized and who uses VC++ to be made aware of the VC++ issue, possibly in comments in the value_initialized code, and to use the workaround to get around this bug of defining one's own derived class copy constructor that calls the base class's copy constructor. </p> <p> I strongly feel it is really a bad idea to change or complicate normal design and coding because of the an obvious bug in a particular implementation of a computer language. Please note I consider this as different from a compiler that simply doesn't support some feature of a language, where workarounds may be created for that compiler, so that one can implement some library design in another often less proficient and natural way. Not implementing a templated constructor in a perfectly normal way as opposed to a completely unusual and much harder to use choice can not be right. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Wed, 06 Jan 2010 09:51:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:4 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:4</guid> <description> <p> Hi Edward, I understand you do not want to adapt your proposed constructor, merely because of a Microsoft specific compiler bug. But I think <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/3472/value_init.patch"><span class="icon">​</span>your patch</a> <em>might</em> break some use cases on other compilers as well: </p> <pre class="wiki">class my_integer { value_initialized&lt;int&gt; m_data; public: operator value_initialized&lt;int&gt;() const; operator int() const; }; int main() { my_integer my; value_initialized&lt;int&gt; val(my); } </pre><p> The above example will become ambiguous when your proposed constructor is added, also according to GCC 4.1.2: <a class="ext-link" href="http://codepad.org/zukxSDbB"><span class="icon">​</span>http://codepad.org/zukxSDbB</a> </p> <p> I think there's a trade off between safety and convenience here. BTW, why did you add an <code>explicit</code> keyword to your constructor? </p> </description> <category>Ticket</category> </item> <item> <author>Edward Diener <eld@…></author> <pubDate>Thu, 07 Jan 2010 05:22:17 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:5 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:5</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3472#comment:4" title="Comment 4">niels_dekker</a>: </p> <blockquote class="citation"> <p> Hi Edward, I understand you do not want to adapt your proposed constructor, merely because of a Microsoft specific compiler bug. But I think <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/3472/value_init.patch"><span class="icon">​</span>your patch</a> <em>might</em> break some use cases on other compilers as well: </p> <pre class="wiki">class my_integer { value_initialized&lt;int&gt; m_data; public: operator value_initialized&lt;int&gt;() const; operator int() const; }; int main() { my_integer my; value_initialized&lt;int&gt; val(my); } </pre><p> The above example will become ambiguous when your proposed constructor is added, also according to GCC 4.1.2: <a class="ext-link" href="http://codepad.org/zukxSDbB"><span class="icon">​</span>http://codepad.org/zukxSDbB</a> </p> <p> I think there's a trade off between safety and convenience here. BTW, why did you add an <code>explicit</code> keyword to your constructor? </p> </blockquote> <p> It sounds to me that you are rejecting any class that has a constructor which takes a single parameter because it may lead to an ambiguous situation like the one you show above. That seems to me to be unnecessarily restrictive and would eliminate much of C++ class design as it has previously been practiced. Consider: </p> <p> struct X { X() {} X(const X &amp; value) {} X(int value) {} }; </p> <p> struct Y { Y():anInt(5) {} operator X() const {return anX;} operator int() const {return anInt} private: X anX; int anInt; }; </p> <p> int main() { Y aY; X anotherX(ay); <em> ambiguity X YetAnotherX(static_cast&lt;X&gt;(ay)); </em> eliminates ambiguity X YetAgainX(static_cast&lt;int&gt;(ay)); <em> eliminates ambiguity } </em></p> <p> One can create this situation with any class, like X, which has a constructor taking a single value. So I still do not see the point of yout objection to this very common usage in value_initialized. I know, or I think I know, that you can't seriously be suggesting that all classes with any constructors which take a single parameter are badly designed, and therefore need to add a second dummy parameter in each case just to avoid the possibly ambiguity as ou showed and I have shown above. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Thu, 07 Jan 2010 18:46:44 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:6 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:6</guid> <description> <p> Replying to <a class="ticket" href="https://svn.boost.org/trac10/ticket/3472#comment:5" title="Comment 5">Edward Diener</a>: </p> <blockquote class="citation"> <p> It sounds to me that you are rejecting any class that has a constructor which takes a single parameter because it may lead to an ambiguous situation like the one you show above. </p> </blockquote> <p> I am not rejecting <em>any class</em> that has a constructor which takes a single parameter. Although I have to admit, both <a class="ext-link" href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=522094"><span class="icon">​</span>that particular Visual C++ bug report of yours</a> and <a class="ext-link" href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n3006.html#535"><span class="icon">​</span>CWG issue 535, "Copy construction without a copy constructor"</a> have made me more aware that such a constructor may cause confusion or ambiguity. </p> <p> But I do think <code>value_initialized</code> should be dealt with with extra care. Because it is around now for more than seven years, and I assume it is used in quite a lot of programs worldwide. Thereby <code>value_initialized</code> is by its nature <em>very</em> generic, so it's very well possible that your proposed change might break some user code in an unexpected way. Moreover, your proposed constructor offers a <em>loophole</em>, which allows to break the class invariant, being that <code>value_initialized</code> holds an object that has been value-initialized. </p> <p> Now it might in some cases be acceptable to break backward compatibility. And I think that there are very good reasons to allow storing a <em>direct-initialized</em> object into a <code>value_initialized</code> wrapper. But I just think the considerations above have to be taken into account when deciding how to resolve your value_init request. </p> <p> I'm certainly not against <a class="ext-link" href="https://svn.boost.org/trac/boost/attachment/ticket/3472/value_init.patch"><span class="icon">​</span>your proposed patch</a>, it's just that I would prefer to add a tag parameter (for example, <em>boost::direct_initialized</em>) to your constructor. But it appears that you're strongly opposed to that idea of mine, right? </p> <p> Anyway, I just hope Fernando can make the right choice :-) </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Wed, 31 Mar 2010 14:37:12 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:7 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:7</guid> <description> <p> Jeffrey Hellrung suggested defining a new template class that offers both value-initialization and direct-initialization: <em>Re: [boost][utility/value_init] boost::value_initialized&lt;T&gt; direct-initialized?</em>, <a class="ext-link" href="http://lists.boost.org/Archives/boost/2010/03/164331.php"><span class="icon">​</span>http://lists.boost.org/Archives/boost/2010/03/164331.php</a> The new template class could simply be named <em>boost::initialized&lt;T&gt;</em>. value_initialized&lt;T&gt; could then be implemented in terms of initialized&lt;T&gt;. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Sat, 03 Apr 2010 12:23:58 GMT</pubDate> <title>attachment set https://svn.boost.org/trac10/ticket/3472 https://svn.boost.org/trac10/ticket/3472 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">initialized.patch</span> </li> </ul> <p> Adds a new template class to value_init.hpp: boost::initialized&lt;T&gt; </p> Ticket niels_dekker Sat, 01 May 2010 22:04:58 GMT attachment set https://svn.boost.org/trac10/ticket/3472 https://svn.boost.org/trac10/ticket/3472 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">initialized_documentation.patch</span> </li> </ul> <p> documentation for boost::initialized&lt;T&gt; </p> Ticket niels_dekker Sun, 02 May 2010 09:52:21 GMT attachment set https://svn.boost.org/trac10/ticket/3472 https://svn.boost.org/trac10/ticket/3472 <ul> <li><strong>attachment</strong> → <span class="trac-field-new">initialized_test.patch</span> </li> </ul> <p> tests for boost::initialized&lt;T&gt; (fixed a few typo's) </p> Ticket niels_dekker Sun, 09 May 2010 20:51:31 GMT <link>https://svn.boost.org/trac10/ticket/3472#comment:8 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:8</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/61883" title="Added boost::initialized&lt;T&gt; as was agreed at ...">[61883]</a>) Added boost::initialized&lt;T&gt; as was agreed at <a class="ext-link" href="http://lists.boost.org/Archives/boost/2010/04/164916.php"><span class="icon">​</span>http://lists.boost.org/Archives/boost/2010/04/164916.php</a> -- see <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3472" title="#3472: Feature Requests: Setting value_initialized&lt;T&gt; to a value when T is a top-level const (closed: fixed)">#3472</a> </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Sun, 04 Jul 2010 21:56:49 GMT</pubDate> <title/> <link>https://svn.boost.org/trac10/ticket/3472#comment:9 </link> <guid isPermaLink="false">https://svn.boost.org/trac10/ticket/3472#comment:9</guid> <description> <p> (In <a class="changeset" href="https://svn.boost.org/trac10/changeset/63638" title="Merged value_init fixes (extra tests + documentation) from trunk, see ...">[63638]</a>) Merged value_init fixes (extra tests + documentation) from trunk, see <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3472" title="#3472: Feature Requests: Setting value_initialized&lt;T&gt; to a value when T is a top-level const (closed: fixed)">#3472</a>, <a class="closed ticket" href="https://svn.boost.org/trac10/ticket/3869" title="#3869: Bugs: Unconditional call to memset in value_initialized() (closed: fixed)">#3869</a>. </p> </description> <category>Ticket</category> </item> <item> <dc:creator>niels_dekker</dc:creator> <pubDate>Thu, 15 Jul 2010 10:25:42 GMT</pubDate> <title>status changed; resolution set https://svn.boost.org/trac10/ticket/3472#comment:10 https://svn.boost.org/trac10/ticket/3472#comment:10 <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> <p> Fixed for Boost release 1.44, by having added boost::initialized&lt;T&gt;. </p> Ticket